Browse Source

0.8.1011

* optimized communication
* repaired statistics
* fixed reboot
pull/1239/head
lumapu 11 months ago
parent
commit
bac4301b8a
  1. 140
      src/hm/Communication.h
  2. 2
      src/hm/Heuristic.h

140
src/hm/Communication.h

@ -46,7 +46,7 @@ class Communication : public CommQueue<> {
if(!valid)
return; // empty
uint16_t timeout = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment && q->iv->mGotLastMsg) ? SINGLEFR_TIMEOUT : DEFAULT_TIMEOUT);
uint16_t timeout = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment && q->iv->mGotLastMsg) || mIsResend) ? SINGLEFR_TIMEOUT : DEFAULT_TIMEOUT;
uint16_t timeout_min = (q->iv->ivGen == IV_MI) ? MI_TIMEOUT : ((q->iv->mGotFragment) ? SINGLEFR_TIMEOUT : FRSTMSG_TIMEOUT);
switch(mState) {
@ -84,10 +84,13 @@ class Communication : public CommQueue<> {
q->iv->radio->sendControlPacket(q->iv, q->cmd, q->iv->powerLimit, false);
} else
q->iv->radio->prepareDevInformCmd(q->iv, q->cmd, q->ts, q->iv->alarmLastId, false);
if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.txCnt++;
mWaitTimeout = millis() + timeout;
mWaitTimeout_min = millis() + timeout_min;
mIsResend = false;
mlastTO_min = timeout_min;
setAttempt();
mState = States::WAIT;
break;
@ -100,10 +103,13 @@ class Communication : public CommQueue<> {
mWaitTimeout = mWaitTimeout_min;
}
} else if(mFirstTry) {
if(*mSerialDebug) {
DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(String(millis() - mWaitTimeout_min + timeout_min));
DBGPRINT(String(millis() - mWaitTimeout_min + mlastTO_min));
DBGPRINTLN(F("ms - second try"));
}
mFirstTry = false;
mlastTO_min = timeout_min;
if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.retransmits++; // got nothing
mState = States::START;
@ -117,12 +123,14 @@ class Communication : public CommQueue<> {
break;
case States::CHECK_FRAMES: {
if(!q->iv->radio->get() || ((q->iv->mGotFragment) && (0 == q->attempts))) { // radio buffer empty
cmdDone();
if((!q->iv->radio->get() && !mIsResend) || ((q->iv->mGotFragment) && (0 == q->attempts))) { // radio buffer empty
//cmdDone();
if(*mSerialDebug) {
DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(F("request timeout: "));
DBGPRINT(String(millis() - mWaitTimeout + timeout));
DBGPRINTLN(F("ms"));
}
if(!q->iv->mGotFragment) {
if((IV_HMS == q->iv->ivGen) || (IV_HMT == q->iv->ivGen)) {
@ -130,11 +138,12 @@ class Communication : public CommQueue<> {
mWaitTimeout = millis() + 1000;
}
}
closeRequest(q->iv, false);
closeRequest(q->iv, false, false);
break;
}
mFirstTry = false; // for correct reset
States nextState = States::RESET;
while(!q->iv->radio->mBufCtrl.empty()) {
packet_t *p = &q->iv->radio->mBufCtrl.front();
@ -185,8 +194,23 @@ class Communication : public CommQueue<> {
}
if((0 == q->attempts) && (!q->iv->mGotFragment))
closeRequest(q->iv, false);
else
else {
if(q->iv->ivGen != IV_MI)
mState = nextState;
else {
if( q->iv->miMultiParts > 5 &&
((q->cmd == 0x39) && (q->iv->type == INV_TYPE_4CH) ||
(q->cmd == MI_REQ_CH2) && (q->iv->type == INV_TYPE_2CH) ||
(q->cmd == MI_REQ_CH1) && (q->iv->type == INV_TYPE_1CH))) {
miComplete(q->iv);
//closeRequest(q->iv, q->iv->miMultiParts > 5);
} else if (q->iv->miMultiParts > 5)
closeRequest(q->iv, true);
else {
nextState = States::WAIT;
}
}
}
}
break;
@ -223,6 +247,8 @@ class Communication : public CommQueue<> {
DBGPRINT(String(q->attempts));
DBGPRINTLN(F(" attempts left)"));
sendRetransmit(q, framnr-1);
mIsResend = true;
mlastTO_min = timeout_min;
return;
}
@ -292,7 +318,7 @@ class Communication : public CommQueue<> {
record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the record structure
rec->ts = q->ts;
miStsConsolidate(q, ((p->packet[0] == 0x88) ? 1 : 2), rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
mHeu.setGotFragment(q->iv);
//mHeu.setGotFragment(q->iv); only do this when we are through the cycle?
}
}
@ -331,9 +357,11 @@ class Communication : public CommQueue<> {
DBGPRINT(F("CRC Error "));
if(q->attempts == 0) {
DBGPRINTLN(F("-> Fail"));
if(!mHeu.getTestModeEnabled())
/*if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.rxFail++; // got fragments but not complete response
cmdDone();
cmdDone();*/
closeRequest(q->iv, false, false);
} else
DBGPRINTLN(F("-> complete retransmit"));
mState = States::RESET;
@ -374,11 +402,15 @@ class Communication : public CommQueue<> {
return;
}
if((rec->pyldLen != len) && (0 != rec->pyldLen)) {
if(*mSerialDebug) {
DPRINT(DBG_ERROR, F("plausibility check failed, expected "));
DBGPRINT(String(rec->pyldLen));
DBGPRINTLN(F(" bytes"));
if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.rxFail++;
}
/*if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.rxFail++;*/
closeRequest(q->iv, false, false);
return;
}
@ -415,23 +447,22 @@ class Communication : public CommQueue<> {
}
private:
void closeRequest(Inverter<> *iv, bool succeeded = true) {
void closeRequest(Inverter<> *iv, bool succeeded = true, bool delCmd = true) {
// ordering of lines is relevant for statistics
if(succeeded) {
mHeu.setGotAll(iv);
if(!mHeu.getTestModeEnabled())
iv->radioStatistics.rxSuccess++;
cmdDone(true);
} else if(iv->mGotFragment) {
mHeu.setGotFragment(iv);
if(!mHeu.getTestModeEnabled())
iv->radioStatistics.rxFail++; // got no complete payload
cmdDone(true);
} else {
mHeu.setGotNothing(iv);
if(!mHeu.getTestModeEnabled())
iv->radioStatistics.rxFailNoAnser++; // got nothing
cmdDone();
mHeu.setGotNothing(iv);
}
cmdDone(delCmd);
iv->mGotFragment = false;
iv->mGotLastMsg = false;
iv->miMultiParts = 0;
@ -482,11 +513,11 @@ class Communication : public CommQueue<> {
q->iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1);
}
q->iv->isConnected = true;
//if(mSerialDebug) {
if(*mSerialDebug) {
DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(F("HW_VER is "));
DBGPRINTLN(String((p->packet[24] << 8) + p->packet[25]));
//}
}
record_t<> *rec = q->iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
rec->ts = q->ts;
q->iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])/1);
@ -508,7 +539,7 @@ class Communication : public CommQueue<> {
rec->ts = q->ts;
q->iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1);
//if(mSerialDebug) {
if(*mSerialDebug) {
DPRINT(DBG_INFO,F("HW_FB_TLmValue "));
DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15]));
DBGPRINT(F("HW_FB_ReSPRT "));
@ -519,7 +550,7 @@ class Communication : public CommQueue<> {
DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21]));
DBGPRINT(F("Matching_APPFW_PN "));
DBGPRINTLN(String((uint32_t) (((p->packet[22] << 8) | p->packet[23]) << 8 | p->packet[24]) << 8 | p->packet[25]));
//}
}
if(NULL != mCbPayload)
(mCbPayload)(InverterDevInform_All, q->iv);
q->iv->miMultiParts +=2;
@ -537,22 +568,23 @@ class Communication : public CommQueue<> {
byte[15] byte[16] PNInfoCRC_gusv
byte[15] byte[16] PNInfoCRC_gusv (this really is double mentionned in xlsx...)
*/
//if(mSerialDebug) {
if(*mSerialDebug) {
DPRINT(DBG_INFO,F("APPFW_MINVER "));
DBGPRINTLN(String((p->packet[10] << 8) + p->packet[11]));
DBGPRINT(F("HWInfoAddr "));
DBGPRINTLN(String((p->packet[12] << 8) + p->packet[13]));
DBGPRINT(F("PNInfoCRC_gusv "));
DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15]));
//}
}
if(NULL != mCbPayload)
(mCbPayload)(InverterDevInform_Simple, q->iv);
q->iv->miMultiParts++;
}
if(q->iv->miMultiParts > 5)
closeRequest(q->iv, true);
else
mState = States::WAIT;
//if(q->iv->miMultiParts > 5)
//closeRequest(q->iv, true);
//else
//if(q->iv->miMultiParts < 6)
// mState = States::WAIT;
/*if (mPayload[iv->id].multi_parts > 5) {
iv->setQueuedCmdFinished();
@ -569,7 +601,9 @@ class Communication : public CommQueue<> {
inline void miDataDecode(packet_t *p, const queue_s *q) {
record_t<> *rec = q->iv->getRecordStruct(RealTimeRunData_Debug); // choose the parser
rec->ts = q->ts;
mState = States::RESET;
//mState = States::RESET;
if(q->iv->miMultiParts < 6)
q->iv->miMultiParts += 6;
uint8_t datachan = ( p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES) || p->packet[0] == (MI_REQ_4CH + ALL_FRAMES) ) ? CH1 :
( p->packet[0] == (MI_REQ_CH2 + ALL_FRAMES) || p->packet[0] == (0x37 + ALL_FRAMES) ) ? CH2 :
@ -605,14 +639,10 @@ class Communication : public CommQueue<> {
miStsConsolidate(q, datachan, rec, p->packet[23], p->packet[24]);
if (p->packet[0] < (0x39 + ALL_FRAMES) ) {
//addImportant(q->iv, (q->cmd + 1));
//mPayload[iv->id].txCmd++;
//mPayload[iv->id].retransmits = 0; // reserve retransmissions for each response
//mPayload[iv->id].complete = false;
miNextRequest((p->packet[0] - ALL_FRAMES + 1), q);
//mHeu.setGotFragment(q->iv);
} else {
miComplete(q->iv);
q->iv->miMultiParts = 7; // indicate we are ready
//miComplete(q->iv);
}
} else if((p->packet[0] == (MI_REQ_CH1 + ALL_FRAMES)) && (q->iv->type == INV_TYPE_2CH)) {
//addImportant(q->iv, MI_REQ_CH2);
@ -620,29 +650,39 @@ class Communication : public CommQueue<> {
//use also miMultiParts here for better statistics?
//mHeu.setGotFragment(q->iv);
} else { // first data msg for 1ch, 2nd for 2ch
miComplete(q->iv);
q->iv->miMultiParts += 6; // indicate we are ready
//miComplete(q->iv);
}
}
void miNextRequest(uint8_t cmd, const queue_s *q) {
incrAttempt(); // if function is called, we got something, and we necessarily need more transmissions for MI types...
if(*mSerialDebug) {
DPRINT_IVID(DBG_WARN, q->iv->id);
DBGPRINT(F("next request ("));
DBGPRINT(String(q->attempts));
DBGPRINT(F(" attempts left): 0x"));
DBGHEXLN(cmd);
}
//if(q->attempts) {
if(q->iv->miMultiParts == 7) {
mHeu.setGotAll(q->iv);
if(!mHeu.getTestModeEnabled())
q->iv->radioStatistics.rxSuccess++;
} else
mHeu.setGotFragment(q->iv);
/*if(!mHeu.getTestModeEnabled())
iv->radioStatistics.rxFail++; // got no complete payload*/
//q->iv->radioStatistics.retransmits++;
q->iv->radio->sendCmdPacket(q->iv, cmd, 0x00, true);
q->iv->radioStatistics.retransmits++;
mWaitTimeout = millis() + MI_TIMEOUT;
mWaitTimeout_min = mWaitTimeout;
q->iv->miMultiParts = 0;
q->iv->mGotFragment = 0;
mIsResend = true;
chgCmd(cmd);
mState = States::WAIT;
/*} else {
add(q, true);
cmdDone();
mState = States::RESET;
}*/
//mState = States::WAIT;
}
void miStsConsolidate(const queue_s *q, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) {
@ -694,12 +734,14 @@ class Communication : public CommQueue<> {
}
}
}
//if (mSerialDebug) {
if(*mSerialDebug) {
DPRINT(DBG_WARN, F("New state on CH"));
DBGPRINT(String(stschan)); DBGPRINT(F(" ("));
DBGPRINT(String(prntsts)); DBGPRINT(F("): "));
DBGPRINTLN(q->iv->getAlarmStr(prntsts));
//}
}
if(!q->iv->miMultiParts)
q->iv->miMultiParts = 1; // indicate we got status info (1+2 ch types)
}
if (!stsok) {
@ -709,11 +751,11 @@ class Communication : public CommQueue<> {
if (q->iv->alarmMesIndex < rec->record[q->iv->getPosByChFld(0, FLD_EVT, rec)]) {
q->iv->alarmMesIndex = rec->record[q->iv->getPosByChFld(0, FLD_EVT, rec)]; // seems there's no status per channel in 3rd gen. models?!?
//if (mSerialDebug) {
if (*mSerialDebug) {
DPRINT_IVID(DBG_INFO, q->iv->id);
DBGPRINT(F("alarm ID incremented to "));
DBGPRINTLN(String(q->iv->alarmMesIndex));
//}
}
}
}
@ -746,7 +788,7 @@ class Communication : public CommQueue<> {
// update status state-machine,
if (ac_pow)
iv->isProducing();
closeRequest(iv, true);
closeRequest(iv, iv->miMultiParts > 5);
//mHeu.setGotAll(iv);
//cmdDone(true);
@ -774,7 +816,9 @@ class Communication : public CommQueue<> {
uint32_t mWaitTimeout = 0;
uint32_t mWaitTimeout_min = 0;
std::array<frame_t, MAX_PAYLOAD_ENTRIES> mLocalBuf;
bool mFirstTry = false;
bool mFirstTry = false; // see, if we should do a second try
bool mIsResend = false; // we alrady had waited one complete cycle
uint16_t mlastTO_min = DEFAULT_TIMEOUT; // remember timeout_min for correct calculation
uint8_t mMaxFrameId;
uint8_t mPayload[MAX_BUFFER];
payloadListenerType mCbPayload = NULL;

2
src/hm/Heuristic.h

@ -56,7 +56,7 @@ class Heuristic {
if(!mTestEn) {
updateQuality(iv, -2); // BAD
mTestEn = true;
iv->txRfChId = (iv->txRfChId + 1) % RF_MAX_CHANNEL_ID;
iv->txRfChId = mCycle % RF_MAX_CHANNEL_ID;
}
}

Loading…
Cancel
Save