@ -64,13 +64,28 @@ struct calcFunc_t {
func_t < T > * func ; // function pointer
} ;
enum class MqttSentStatus : uint8_t {
NEW_DATA ,
LAST_SUCCESS_SENT ,
DATA_SENT
} ;
enum class InverterStatus : uint8_t {
OFF ,
STARTING ,
PRODUCING ,
WAS_PRODUCING ,
WAS_ON
} ;
template < class T = float >
struct record_t {
byteAssign_t * assign ; // assignment of bytes in payload
uint8_t length ; // length of the assignment list
T * record ; // data pointer
uint32_t ts ; // timestamp of last received payload
uint8_t pyldLen ; // expected payload length for plausibility check
byteAssign_t * assign ; // assignment of bytes in payload
uint8_t length ; // length of the assignment list
T * record ; // data pointer
uint32_t ts ; // timestamp of last received payload
uint8_t pyldLen ; // expected payload length for plausibility check
MqttSentStatus mqttSentStatus ; // indicates the current MqTT sent status
} ;
struct alarm_t {
@ -94,14 +109,6 @@ const calcFunc_t<T> calcFunctions[] = {
{ CALC_MPDC_CH , & calcMaxPowerDc }
} ;
enum class InverterStatus : uint8_t {
OFF ,
STARTING ,
PRODUCING ,
WAS_PRODUCING ,
WAS_ON
} ;
template < class REC_TYP >
class Inverter {
public :
@ -124,26 +131,28 @@ class Inverter {
bool isConnected ; // shows if inverter was successfully identified (fw version and hardware info)
InverterStatus status ; // indicates the current inverter status
std : : array < alarm_t , 10 > lastAlarm ; // holds last 10 alarms
uint8_t alarmNxtWrPos ; // indicates the position in array (rolling buffer)
int8_t rssi ; // RSSI
uint16_t alarmCnt ; // counts the total number of occurred alarms
uint16_t alarmLastId ; // lastId which was received
int8_t rssi ; // RSSI
uint8_t mCmd ; // holds the command to send
bool mGotFragment ; // shows if inverter has sent at least one fragment
uint8_t miMultiParts ; // helper info for MI multiframe msgs
uint8_t outstandingFrames ; // helper info to count difference between expected and received frames
bool mGotFragment ; // shows if inverter has sent at least one fragment
uint8_t curFrmCnt ; // count received frames in current loop
bool mGotLastMsg ; // shows if inverter has already finished transmission cycle
uint8_t mCmd ; // holds the command to send
bool mIsSingleframeReq ; // indicates this is a missing single frame request
Radio * radio ; // pointer to associated radio class
statistics_t radioStatistics ; // information about transmitted, failed, ... packets
HeuristicInv heuristics ; // heuristic information / logic
uint8_t curCmtFreq ; // current used CMT frequency, used to check if freq. was changed during runtime
bool commEnabled ; // 'pause night communication' sets this field to false
uint32_t tsMaxAcPower ; // holds the timestamp when the MaxAC power was seen
static uint32_t * timestamp ; // system timestamp
static cfgInst_t * generalConfig ; // general inverter configuration from setup
public :
Inverter ( ) {
ivGen = IV_HM ;
powerLimit [ 0 ] = 0xffff ; // 6553.5 W Limit -> unlimited
@ -155,7 +164,6 @@ class Inverter {
alarmMesIndex = 0 ;
isConnected = false ;
status = InverterStatus : : OFF ;
alarmNxtWrPos = 0 ;
alarmCnt = 0 ;
alarmLastId = 0 ;
rssi = - 127 ;
@ -165,6 +173,7 @@ class Inverter {
mIsSingleframeReq = false ;
radio = NULL ;
commEnabled = true ;
tsMaxAcPower = 0 ;
memset ( & radioStatistics , 0 , sizeof ( statistics_t ) ) ;
memset ( heuristics . txRfQuality , - 6 , 5 ) ;
@ -310,11 +319,11 @@ class Inverter {
rec - > record [ pos ] = ( REC_TYP ) ( val ) ;
}
}
rec - > mqttSentStatus = MqttSentStatus : : NEW_DATA ;
}
if ( rec = = & recordMeas ) {
DPRINTLN ( DBG_VERBOSE , " add real time " ) ;
// get last alarm message index and save it in the inverter object
if ( getPosByChFld ( 0 , FLD_EVT , rec ) = = pos ) {
if ( alarmMesIndex < rec - > record [ pos ] ) {
@ -498,6 +507,7 @@ class Inverter {
DPRINTLN ( DBG_VERBOSE , F ( " hmInverter.h:initAssignment " ) ) ;
rec - > ts = 0 ;
rec - > length = 0 ;
rec - > mqttSentStatus = MqttSentStatus : : DATA_SENT ; // nothing new to transmit
switch ( cmd ) {
case RealTimeRunData_Debug :
if ( INV_TYPE_1CH = = type ) {
@ -582,7 +592,7 @@ class Inverter {
void resetAlarms ( ) {
lastAlarm . fill ( { 0 , 0 , 0 } ) ;
a larmNxtWrPos = 0 ;
mA larmNxtWrPos = 0 ;
alarmCnt = 0 ;
alarmLastId = 0 ;
@ -596,10 +606,18 @@ class Inverter {
uint16_t txCnt = ( pyld [ 2 ] < < 8 ) + pyld [ 3 ] ;
if ( mIvRxCnt | | mIvTxCnt ) { // there was successful GetLossRate in the past
radioStatistics . ivLoss = mDtuTxCnt - ( rxCnt - mIvRxCnt ) ;
radioStatistics . ivSent = mDtuTxCnt ;
radioStatistics . dtuLoss = txCnt - mIvTxCnt - mDtuRxCnt ;
radioStatistics . dtuSent = txCnt - mIvTxCnt ;
if ( rxCnt < mIvRxCnt ) // overflow
radioStatistics . ivLoss = radioStatistics . ivSent - ( rxCnt + ( ( uint16_t ) 65535 - mIvRxCnt ) + 1 ) ;
else
radioStatistics . ivLoss = radioStatistics . ivSent - ( rxCnt - mIvRxCnt ) ;
if ( txCnt < mIvTxCnt ) // overflow
radioStatistics . dtuSent = txCnt + ( ( uint16_t ) 65535 - mIvTxCnt ) + 1 ;
else
radioStatistics . dtuSent = txCnt - mIvTxCnt ;
radioStatistics . dtuLoss = radioStatistics . dtuSent - mDtuRxCnt ;
DPRINT_IVID ( DBG_INFO , id ) ;
DBGPRINT ( F ( " Inv loss: " ) ) ;
@ -790,9 +808,9 @@ class Inverter {
private :
inline void addAlarm ( uint16_t code , uint32_t start , uint32_t end ) {
lastAlarm [ a larmNxtWrPos] = alarm_t ( code , start , end ) ;
if ( + + a larmNxtWrPos > = 10 ) // rolling buffer
a larmNxtWrPos = 0 ;
lastAlarm [ mA larmNxtWrPos] = alarm_t ( code , start , end ) ;
if ( + + mA larmNxtWrPos > = 10 ) // rolling buffer
mA larmNxtWrPos = 0 ;
}
void toRadioId ( void ) {
@ -813,6 +831,7 @@ class Inverter {
uint8_t mGetLossInterval ; // request iv every AHOY_GET_LOSS_INTERVAL RealTimeRunData_Debug
uint16_t mIvRxCnt = 0 ;
uint16_t mIvTxCnt = 0 ;
uint8_t mAlarmNxtWrPos = 0 ; // indicates the position in array (rolling buffer)
public :
uint16_t mDtuRxCnt = 0 ;
@ -948,8 +967,10 @@ static T calcMaxPowerDc(Inverter<> *iv, uint8_t arg0) {
dcMaxPower = iv - > getValue ( i , rec ) ;
}
}
if ( dcPower > dcMaxPower )
if ( dcPower > dcMaxPower ) {
iv - > tsMaxAcPower = * iv - > timestamp ;
return dcPower ;
}
}
return dcMaxPower ;
}