* fix display of sunrise in `/system` #1308
* fix overflow of `getLossRate` calculation #1318
* improved MqTT by marking sent data and improved `last_success` resends #1319
* added timestamp for `max ac power` as tooltip #1324 #1123 #1199
* repaired Power-limit acknowledge #1322
This commit is contained in:
lumapu 2024-01-05 01:24:38 +01:00
parent 0d10d19b30
commit 31ecb9620f
13 changed files with 97 additions and 87 deletions

View file

@ -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});
alarmNxtWrPos = 0;
mAlarmNxtWrPos = 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[alarmNxtWrPos] = alarm_t(code, start, end);
if(++alarmNxtWrPos >= 10) // rolling buffer
alarmNxtWrPos = 0;
lastAlarm[mAlarmNxtWrPos] = alarm_t(code, start, end);
if(++mAlarmNxtWrPos >= 10) // rolling buffer
mAlarmNxtWrPos = 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;
}