|  |  | @ -24,6 +24,7 @@ typedef struct { | 
			
		
	
		
			
				
					|  |  |  |     uint8_t txId; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t invId; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t retransmits; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t skipfirstrepeat; | 
			
		
	
		
			
				
					|  |  |  |     bool gotFragment; | 
			
		
	
		
			
				
					|  |  |  |     /*
 | 
			
		
	
		
			
				
					|  |  |  |     uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; | 
			
		
	
	
		
			
				
					|  |  | @ -93,12 +94,14 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             DBGPRINT(F(") prepareDevInformCmd 0x")); | 
			
		
	
		
			
				
					|  |  |  |             DBGPRINTLN(String(cmd, HEX)); | 
			
		
	
		
			
				
					|  |  |  |             uint8_t cmd2 = cmd; | 
			
		
	
		
			
				
					|  |  |  |             if (cmd == 0x1 ) { | 
			
		
	
		
			
				
					|  |  |  |                 cmd  = TX_REQ_INFO; | 
			
		
	
		
			
				
					|  |  |  |             if (cmd == 0x1 ) { //0x1
 | 
			
		
	
		
			
				
					|  |  |  |                 cmd  = 0x0f; | 
			
		
	
		
			
				
					|  |  |  |                 cmd2 = 0x00; | 
			
		
	
		
			
				
					|  |  |  |                 mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd2, false); | 
			
		
	
		
			
				
					|  |  |  |             } else { | 
			
		
	
		
			
				
					|  |  |  |                 mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd2, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
			
				
					|  |  |  |             }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd2, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
			
				
					|  |  |  |             mPayload[iv->id].txCmd = cmd; | 
			
		
	
		
			
				
					|  |  |  |             if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) { | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].dataAB[CH1] = false; | 
			
		
	
	
		
			
				
					|  |  | @ -154,7 +157,41 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                     //iv->setQueuedCmdFinished();
 | 
			
		
	
		
			
				
					|  |  |  |                 }*/ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             //}
 | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             else if (p->packet[0] == ( 0x0f + ALL_FRAMES)) { | 
			
		
	
		
			
				
					|  |  |  |                 // MI response from get hardware information request
 | 
			
		
	
		
			
				
					|  |  |  |                 record_t<> *rec = iv->getRecordStruct(InverterDevInform_All);  // choose the record structure
 | 
			
		
	
		
			
				
					|  |  |  |                 rec->ts = mPayload[iv->id].ts; | 
			
		
	
		
			
				
					|  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  | case InverterDevInform_All: | 
			
		
	
		
			
				
					|  |  |  |                     rec->length  = (uint8_t)(HMINFO_LIST_LEN); | 
			
		
	
		
			
				
					|  |  |  |                     rec->assign  = (byteAssign_t *)InfoAssignment; | 
			
		
	
		
			
				
					|  |  |  |                     rec->pyldLen = HMINFO_PAYLOAD_LEN; | 
			
		
	
		
			
				
					|  |  |  |                     break; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | const byteAssign_t InfoAssignment[] = { | 
			
		
	
		
			
				
					|  |  |  |     { FLD_FW_VERSION,           UNIT_NONE,   CH0,  0, 2, 1 }, | 
			
		
	
		
			
				
					|  |  |  |     { FLD_FW_BUILD_YEAR,        UNIT_NONE,   CH0,  2, 2, 1 }, | 
			
		
	
		
			
				
					|  |  |  |     { FLD_FW_BUILD_MONTH_DAY,   UNIT_NONE,   CH0,  4, 2, 1 }, | 
			
		
	
		
			
				
					|  |  |  |     { FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE,   CH0,  6, 2, 1 }, | 
			
		
	
		
			
				
					|  |  |  |     { FLD_HW_ID,                UNIT_NONE,   CH0,  8, 2, 1 } | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  | */ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if ( p->packet[9] == 0x00 ) {//first frame
 | 
			
		
	
		
			
				
					|  |  |  |                     //FLD_FW_VERSION
 | 
			
		
	
		
			
				
					|  |  |  |                     for (uint8_t i = 0; i < 5; i++) { | 
			
		
	
		
			
				
					|  |  |  |                         iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1); | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |                     mStat->rxSuccess++; | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x01, false); | 
			
		
	
		
			
				
					|  |  |  |                 } else if ( p->packet[9] == 0x01 ) {//second frame
 | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") got 2nd frame (hw info)")); | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.sendCmdPacket(iv->radioId.u64, 0x0f, 0x12, false); | 
			
		
	
		
			
				
					|  |  |  |                 } else if ( p->packet[9] == 0x12 ) {//3rd frame
 | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") got 3rd frame (hw info)")); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) {  // response from get information command
 | 
			
		
	
		
			
				
					|  |  |  |             // atm, we just do nothing else than print out what we got...
 | 
			
		
	
	
		
			
				
					|  |  | @ -291,7 +328,8 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                 if (IV_HM == iv->ivGen) // only process MI inverters
 | 
			
		
	
		
			
				
					|  |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && | 
			
		
	
		
			
				
					|  |  |  |                 if ( !mPayload[iv->id].complete && | 
			
		
	
		
			
				
					|  |  |  |                     (mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && | 
			
		
	
		
			
				
					|  |  |  |                     (mPayload[iv->id].txId <  (0x36 + ALL_FRAMES)) && | 
			
		
	
		
			
				
					|  |  |  |                     (mPayload[iv->id].txId >  (0x39 + ALL_FRAMES)) && | 
			
		
	
		
			
				
					|  |  |  |                     (mPayload[iv->id].txId != (0x09 + ALL_FRAMES)) && | 
			
		
	
	
		
			
				
					|  |  | @ -304,6 +342,13 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 //delayed next message?
 | 
			
		
	
		
			
				
					|  |  |  |                 //mPayload[iv->id].skipfirstrepeat++;
 | 
			
		
	
		
			
				
					|  |  |  |                 if (mPayload[iv->id].skipfirstrepeat) { | 
			
		
	
		
			
				
					|  |  |  |                     mPayload[iv->id].skipfirstrepeat = 0; //reset counter*/
 | 
			
		
	
		
			
				
					|  |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (!mPayload[iv->id].complete) { | 
			
		
	
		
			
				
					|  |  |  |                     //DPRINTLN(DBG_INFO, F("Pyld incompl code")); //info for testing only
 | 
			
		
	
		
			
				
					|  |  |  |                     bool crcPass, pyldComplete; | 
			
		
	
	
		
			
				
					|  |  | @ -339,6 +384,10 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                                                 if (!mPayload[iv->id].stsAB[CH1] || !mPayload[iv->id].dataAB[CH1] ) | 
			
		
	
		
			
				
					|  |  |  |                                                     cmd = 0x09; | 
			
		
	
		
			
				
					|  |  |  |                                             } | 
			
		
	
		
			
				
					|  |  |  |                                         } else if ( cmd == 0x0f ) { | 
			
		
	
		
			
				
					|  |  |  |                                             //hard/firmware request; might not work, so just one try...
 | 
			
		
	
		
			
				
					|  |  |  |                                             iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |                                             cmd = iv->getQueuedCmd(); | 
			
		
	
		
			
				
					|  |  |  |                                         } | 
			
		
	
		
			
				
					|  |  |  |                                         DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") next request is 0x") + String(cmd, HEX)); | 
			
		
	
		
			
				
					|  |  |  |                                         //mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd, true);
 | 
			
		
	
	
		
			
				
					|  |  | @ -357,7 +406,9 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                             DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); | 
			
		
	
		
			
				
					|  |  |  |                             mSys->Radio.prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } else {  // payload complete
 | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     /*else {  // payload complete
 | 
			
		
	
		
			
				
					|  |  |  |                         //This tree is not really tested, most likely it's not truly complete....
 | 
			
		
	
		
			
				
					|  |  |  |                         DPRINTLN(DBG_INFO, F("procPyld: cmd:  0x") + String(mPayload[iv->id].txCmd, HEX)); | 
			
		
	
		
			
				
					|  |  |  |                         DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, HEX)); | 
			
		
	
		
			
				
					|  |  |  |                         //DPRINTLN(DBG_DEBUG, F("procPyld: max:  ") + String(mPayload[iv->id].maxPackId));
 | 
			
		
	
	
		
			
				
					|  |  | @ -371,7 +422,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                         record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the parser
 | 
			
		
	
		
			
				
					|  |  |  |                         iv->setValue(iv->getPosByChFld(0, FLD_PAC, rec), rec, (float) (ac_pow/10)); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         DPRINTLN(DBG_INFO, F("proces: compl. set of msgs detected")); | 
			
		
	
		
			
				
					|  |  |  |                         DPRINTLN(DBG_INFO, F("process: compl. set of msgs detected")); | 
			
		
	
		
			
				
					|  |  |  |                         iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); | 
			
		
	
		
			
				
					|  |  |  |                         iv->doCalculations(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -425,7 +476,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         iv->setQueuedCmdFinished(); */ | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     //}*/
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 yield(); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
	
		
			
				
					|  |  | @ -466,15 +517,17 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ | 
			
		
	
		
			
				
					|  |  |  |                 iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; // seems there's no status per channel in 3rd gen. models?!?
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(iv->alarmMesIndex)); | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") alarm ID incremented to ") + String(iv->alarmMesIndex)); | 
			
		
	
		
			
				
					|  |  |  |                 iv->enqueCommand<InfoCommand>(AlarmData); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             //mPayload[iv->id].skipfirstrepeat = 1;
 | 
			
		
	
		
			
				
					|  |  |  |             if (mPayload[iv->id].stsAB[CH0] && mPayload[iv->id].dataAB[CH0] && !mPayload[iv->id].complete) { | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].complete = true; | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("rec. complete set of msgs")); | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") got all msgs")); | 
			
		
	
		
			
				
					|  |  |  |                 iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); | 
			
		
	
		
			
				
					|  |  |  |                 iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |                 iv->doCalculations(); | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].skipfirstrepeat = 0; | 
			
		
	
		
			
				
					|  |  |  |                 notify(mPayload[iv->id].txCmd); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -561,11 +614,11 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_PAC, rec), rec, (float) (ac_pow/10)); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if ( mPayload[iv->id].complete || //4ch device
 | 
			
		
	
		
			
				
					|  |  |  |                  ((iv->type != INV_TYPE_4CH)     //other devices
 | 
			
		
	
		
			
				
					|  |  |  |                  iv->type != INV_TYPE_4CH     //other devices
 | 
			
		
	
		
			
				
					|  |  |  |                  && mPayload[iv->id].dataAB[CH0] | 
			
		
	
		
			
				
					|  |  |  |                  && mPayload[iv->id].stsAB[CH0])) { | 
			
		
	
		
			
				
					|  |  |  |                  && mPayload[iv->id].stsAB[CH0] ) { | 
			
		
	
		
			
				
					|  |  |  |                     mPayload[iv->id].complete = true; // For 2 CH devices, this might be too short...
 | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_INFO, F("rec. complete set of msgs")); | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") got all msgs")); | 
			
		
	
		
			
				
					|  |  |  |                     iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); | 
			
		
	
		
			
				
					|  |  |  |                     iv->doCalculations(); | 
			
		
	
		
			
				
					|  |  |  |                 /*} else {
 | 
			
		
	
	
		
			
				
					|  |  | @ -620,7 +673,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             //uint8_t cmd = getQueuedCmd();
 | 
			
		
	
		
			
				
					|  |  |  |             if(!*complete) { | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_VERBOSE, F("incomlete, txCmd is 0x") + String(txCmd, HEX)); // + F("cmd is 0x") + String(cmd, HEX));
 | 
			
		
	
		
			
				
					|  |  |  |                 if (txCmd == 0x09 || txCmd == 0x11 || (txCmd >= 0x36 && txCmd <= 0x39)) | 
			
		
	
		
			
				
					|  |  |  |                 if (txCmd == 0x09 || txCmd == 0x11 || txCmd >= 0x36 && txCmd <= 0x39 ) | 
			
		
	
		
			
				
					|  |  |  |                     return false; | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -654,6 +707,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].stsAB[CH1]  = true; //required for 1CH and 2CH devices
 | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].stsAB[CH2]  = true; //only required for 2CH devices
 | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].txCmd       = 0; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].skipfirstrepeat   = 0; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].requested   = false; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].ts          = *mTimestamp; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].sts[0]      = 0; //disable this in case gotFragment is not working
 | 
			
		
	
	
		
			
				
					|  |  | 
 |