|  |  | @ -6,6 +6,7 @@ | 
			
		
	
		
			
				
					|  |  |  | #ifndef __MI_PAYLOAD_H__ | 
			
		
	
		
			
				
					|  |  |  | #define __MI_PAYLOAD_H__ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | //#include "hmInverter.h"
 | 
			
		
	
		
			
				
					|  |  |  | #include "../utils/dbg.h" | 
			
		
	
		
			
				
					|  |  |  | #include "../utils/crc.h" | 
			
		
	
		
			
				
					|  |  |  | #include "../config/config.h" | 
			
		
	
	
		
			
				
					|  |  | @ -21,12 +22,12 @@ typedef struct { | 
			
		
	
		
			
				
					|  |  |  |     bool stsb; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t txId; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t invId; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t retransmits; | 
			
		
	
		
			
				
					|  |  |  |     /*
 | 
			
		
	
		
			
				
					|  |  |  |     uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     uint8_t maxPackId; | 
			
		
	
		
			
				
					|  |  |  |     bool lastFound; | 
			
		
	
		
			
				
					|  |  |  |     uint8_t retransmits; | 
			
		
	
		
			
				
					|  |  |  |     bool gotFragment;*/ | 
			
		
	
		
			
				
					|  |  |  | } miPayload_t; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -49,6 +50,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                 reset(i); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             mSerialDebug  = false; | 
			
		
	
		
			
				
					|  |  |  |             mHighPrioIv   = NULL; | 
			
		
	
		
			
				
					|  |  |  |             mCbMiPayload  = NULL; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -60,8 +62,19 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             mCbMiPayload = cb; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void loop() {} | 
			
		
	
		
			
				
					|  |  |  |         void addAlarmListener(alarmListenerType cb) { | 
			
		
	
		
			
				
					|  |  |  |             mCbMiAlarm = cb; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         void loop() { | 
			
		
	
		
			
				
					|  |  |  |             /*if(NULL != mHighPrioIv) {
 | 
			
		
	
		
			
				
					|  |  |  |                 iv->ivSend(mHighPrioIv, true); // should request firmware version etc.?
 | 
			
		
	
		
			
				
					|  |  |  |                 mHighPrioIv = NULL; | 
			
		
	
		
			
				
					|  |  |  |             }*/ | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void ivSendHighPrio(Inverter<> *iv) { | 
			
		
	
		
			
				
					|  |  |  |             mHighPrioIv = iv; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void ivSend(Inverter<> *iv) { | 
			
		
	
		
			
				
					|  |  |  |             reset(iv->id); | 
			
		
	
	
		
			
				
					|  |  | @ -80,88 +93,46 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |         void add(Inverter<> *iv, packet_t *p) { | 
			
		
	
		
			
				
					|  |  |  |             DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX)); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if (p->packet[0] == (0x08 + ALL_FRAMES)) { // MI status response to 0x09
 | 
			
		
	
		
			
				
					|  |  |  |             if (p->packet[0] == (0x08 + ALL_FRAMES)) { // 0x88; MI status response to 0x09
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].stsa = true; | 
			
		
	
		
			
				
					|  |  |  |                 /*decode here or memcopy payload for later decoding?
 | 
			
		
	
		
			
				
					|  |  |  |                 for decoding see | 
			
		
	
		
			
				
					|  |  |  |                 void MI600StsMsg (NRF24_packet_t *p){ | 
			
		
	
		
			
				
					|  |  |  |                   STAT = (int)((p->packet[11] << 8) + p->packet[12]); | 
			
		
	
		
			
				
					|  |  |  |                   FCNT = (int)((p->packet[13] << 8) + p->packet[14]); | 
			
		
	
		
			
				
					|  |  |  |                   FCODE = (int)((p->packet[15] << 8) + p->packet[16]); | 
			
		
	
		
			
				
					|  |  |  |                 #ifdef ESP8266 | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][5]=STAT; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][6]=FCNT; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][7]=FCODE; | 
			
		
	
		
			
				
					|  |  |  |                 #endif | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 */ | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] == (0x12 + ALL_FRAMES)) { // MI status response to 0x11
 | 
			
		
	
		
			
				
					|  |  |  |                 miStsDecode(iv, p); | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] == (0x11 + SINGLE_FRAME)) { // 0x92; MI status response to 0x11
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].stsb = true; | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  |                 miStsDecode(iv, p, 2); | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] == (0x09 + ALL_FRAMES)) { // MI data response to 0x09
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
			
				
					|  |  |  |                 miDataDecode(iv,p); | 
			
		
	
		
			
				
					|  |  |  |                 iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |                 if (INV_TYPE_2CH == iv->type) { | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); | 
			
		
	
		
			
				
					|  |  |  |                     //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
 | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, 0x11, mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11); | 
			
		
	
		
			
				
					|  |  |  |                 } else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?)
 | 
			
		
	
		
			
				
					|  |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
			
				
					|  |  |  |                     //iv->setQueuedCmdFinished();
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 /*decode here or memcopy payload for later decoding?
 | 
			
		
	
		
			
				
					|  |  |  |                 void MI600DataMsg(NRF24_packet_t *p){ | 
			
		
	
		
			
				
					|  |  |  |                   U_DC =  (float) ((p->packet[11] << 8) + p->packet[12])/10; | 
			
		
	
		
			
				
					|  |  |  |                   I_DC =  (float) ((p->packet[13] << 8) + p->packet[14])/10; | 
			
		
	
		
			
				
					|  |  |  |                   U_AC =  (float) ((p->packet[15] << 8) + p->packet[16])/10; | 
			
		
	
		
			
				
					|  |  |  |                   F_AC =  (float) ((p->packet[17] << 8) + p->packet[18])/100; | 
			
		
	
		
			
				
					|  |  |  |                   P_DC =  (float)((p->packet[19] << 8) + p->packet[20])/10; | 
			
		
	
		
			
				
					|  |  |  |                   Q_DC =  (float)((p->packet[21] << 8) + p->packet[22])/1; | 
			
		
	
		
			
				
					|  |  |  |                   TEMP =  (float) ((p->packet[23] << 8) + p->packet[24])/10; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                   if ((30<U_DC<50) && (0<I_DC<15) && (200<U_AC<300) && (45<F_AC<55) && (0<P_DC<420) && (0<TEMP<80)) | 
			
		
	
		
			
				
					|  |  |  |                    DataOK = 1;  //we need to check this, if no crc
 | 
			
		
	
		
			
				
					|  |  |  |                   else { DEBUG_OUT.printf("Data Wrong!!\r\n");DataOK =0; return;} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                   if (p->packet[2] == 0x89)  {PV= 0; TotalP[1]=P_DC; pvCnt[0]=1;}//port 1
 | 
			
		
	
		
			
				
					|  |  |  |                   if (p->packet[2] == 0x91)  {PV= 1; TotalP[2]=P_DC; pvCnt[1]=1;}//port 2
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                   TotalP[0]=TotalP[1]+TotalP[2]+TotalP[3]+TotalP[4];//in TotalP[0] is the totalPV power
 | 
			
		
	
		
			
				
					|  |  |  |                   if((P_DC>400) || (P_DC<0) || (TotalP[0]>MAXPOWER)){// cant be!!
 | 
			
		
	
		
			
				
					|  |  |  |                     TotalP[0]=0; | 
			
		
	
		
			
				
					|  |  |  |                     return; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 #ifdef ESP8266 | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][0]=PV; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][1]=P_DC; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][2]=U_DC; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][3]=I_DC; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][4]=Q_DC; | 
			
		
	
		
			
				
					|  |  |  |                 #endif | 
			
		
	
		
			
				
					|  |  |  |                   PMI=TotalP[0]; | 
			
		
	
		
			
				
					|  |  |  |                   LIM=(uint16_t)Limit; | 
			
		
	
		
			
				
					|  |  |  |                   PrintOutValues(); | 
			
		
	
		
			
				
					|  |  |  |                 }*/ | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] == (0x11 + ALL_FRAMES)) { // MI data response to 0x11
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].complete = true; | 
			
		
	
		
			
				
					|  |  |  |                 //decode here or memcopy payload for later decoding?
 | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 miDataDecode(iv,p); | 
			
		
	
		
			
				
					|  |  |  |                 iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] <= (0x39 + ALL_FRAMES)) { // MI 1500 data response to 0x11
 | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME)) { // MI 1500 data response to 0x36, 0x37, 0x38 and 0x39
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
			
				
					|  |  |  |                 miDataDecode(iv,p); | 
			
		
	
		
			
				
					|  |  |  |                 iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |                 if (p->packet[0] < (0x39 + ALL_FRAMES)) { | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); | 
			
		
	
		
			
				
					|  |  |  |                     //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES);
 | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, p->packet[0] + 1 - ALL_FRAMES, mPayload[iv->id].ts, iv->alarmMesIndex, false, p->packet[0] + 1 - ALL_FRAMES); | 
			
		
	
		
			
				
					|  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
			
				
					|  |  |  |                     //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0);
 | 
			
		
	
		
			
				
					|  |  |  |                     //iv->setQueuedCmdFinished();
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 //decode here or memcopy payload for later decoding?
 | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter MI1500 ") + String(iv->id) + F(": data msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             /*}
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             /*if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) {  // response from get information command
 | 
			
		
	
		
			
				
					|  |  |  |             if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) {  // response from get information command
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_DEBUG, F("Response from info request received")); | 
			
		
	
		
			
				
					|  |  |  |                 uint8_t *pid = &p->packet[9]; | 
			
		
	
	
		
			
				
					|  |  | @ -184,6 +155,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } */ | 
			
		
	
		
			
				
					|  |  |  |             } else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES)) { // response from dev control command
 | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_DEBUG, F("Response from devcontrol request received")); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -201,7 +173,64 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                     iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 iv->devControlCmd = Init; | 
			
		
	
		
			
				
					|  |  |  |             } else {  // some other response; copied from hmPayload:process; might not be correct to do that here!!!
 | 
			
		
	
		
			
				
					|  |  |  |                 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));
 | 
			
		
	
		
			
				
					|  |  |  |                 record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd);  // choose the parser
 | 
			
		
	
		
			
				
					|  |  |  |                 mPayload[iv->id].complete = true; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 uint8_t payload[128]; | 
			
		
	
		
			
				
					|  |  |  |                 uint8_t payloadLen = 0; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 memset(payload, 0, 128); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 /*for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i++) {
 | 
			
		
	
		
			
				
					|  |  |  |                     memcpy(&payload[payloadLen], mPayload[iv->id].data[i], (mPayload[iv->id].len[i])); | 
			
		
	
		
			
				
					|  |  |  |                     payloadLen += (mPayload[iv->id].len[i]); | 
			
		
	
		
			
				
					|  |  |  |                     yield(); | 
			
		
	
		
			
				
					|  |  |  |                 }*/ | 
			
		
	
		
			
				
					|  |  |  |                 payloadLen -= 2; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (mSerialDebug) { | 
			
		
	
		
			
				
					|  |  |  |                     DPRINT(DBG_INFO, F("Payload (") + String(payloadLen) + "): "); | 
			
		
	
		
			
				
					|  |  |  |                     mSys->Radio.dumpBuf(payload, payloadLen); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (NULL == rec) { | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_ERROR, F("record is NULL!")); | 
			
		
	
		
			
				
					|  |  |  |                 } else if ((rec->pyldLen == payloadLen) || (0 == rec->pyldLen)) { | 
			
		
	
		
			
				
					|  |  |  |                     if (mPayload[iv->id].txId == (TX_REQ_INFO + ALL_FRAMES)) | 
			
		
	
		
			
				
					|  |  |  |                         mStat->rxSuccess++; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     rec->ts = mPayload[iv->id].ts; | 
			
		
	
		
			
				
					|  |  |  |                     for (uint8_t i = 0; i < rec->length; i++) { | 
			
		
	
		
			
				
					|  |  |  |                         iv->addValue(i, payload, rec); | 
			
		
	
		
			
				
					|  |  |  |                         yield(); | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     iv->doCalculations(); | 
			
		
	
		
			
				
					|  |  |  |                     notify(mPayload[iv->id].txCmd); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     if(AlarmData == mPayload[iv->id].txCmd) { | 
			
		
	
		
			
				
					|  |  |  |                         uint8_t i = 0; | 
			
		
	
		
			
				
					|  |  |  |                         uint16_t code; | 
			
		
	
		
			
				
					|  |  |  |                         uint32_t start, end; | 
			
		
	
		
			
				
					|  |  |  |                         while(1) { | 
			
		
	
		
			
				
					|  |  |  |                             code = iv->parseAlarmLog(i++, payload, payloadLen, &start, &end); | 
			
		
	
		
			
				
					|  |  |  |                             if(0 == code) | 
			
		
	
		
			
				
					|  |  |  |                                 break; | 
			
		
	
		
			
				
					|  |  |  |                             if (NULL != mCbMiAlarm) | 
			
		
	
		
			
				
					|  |  |  |                                 (mCbMiAlarm)(code, start, end); | 
			
		
	
		
			
				
					|  |  |  |                             yield(); | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_ERROR, F("plausibility check failed, expected ") + String(rec->pyldLen) + F(" bytes")); | 
			
		
	
		
			
				
					|  |  |  |                     mStat->rxFail++; | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void process(bool retransmit) { | 
			
		
	
	
		
			
				
					|  |  | @ -217,7 +246,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                     // no processing needed if txId is not 0x95
 | 
			
		
	
		
			
				
					|  |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
			
				
					|  |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 }*/ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 if (!mPayload[iv->id].complete) { | 
			
		
	
		
			
				
					|  |  |  |                     bool crcPass, pyldComplete; | 
			
		
	
	
		
			
				
					|  |  | @ -234,7 +263,9 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                             } else { | 
			
		
	
		
			
				
					|  |  |  |                                 if (mPayload[iv->id].retransmits < mMaxRetrans) { | 
			
		
	
		
			
				
					|  |  |  |                                     mPayload[iv->id].retransmits++; | 
			
		
	
		
			
				
					|  |  |  |                                     if(false == mPayload[iv->id].gotFragment) { | 
			
		
	
		
			
				
					|  |  |  |                                     //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
 | 
			
		
	
		
			
				
					|  |  |  |                                     mSys->Radio.sendCmdPacket(iv->radioId.u64, iv->getQueuedCmd(), 24, true); | 
			
		
	
		
			
				
					|  |  |  |                                     /*if(false == mPayload[iv->id].gotFragment) {
 | 
			
		
	
		
			
				
					|  |  |  |                                         DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received")); | 
			
		
	
		
			
				
					|  |  |  |                                         mPayload[iv->id].retransmits = mMaxRetrans; | 
			
		
	
		
			
				
					|  |  |  |                                     } else { | 
			
		
	
	
		
			
				
					|  |  | @ -246,7 +277,7 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                                             } | 
			
		
	
		
			
				
					|  |  |  |                                             yield(); | 
			
		
	
		
			
				
					|  |  |  |                                         } | 
			
		
	
		
			
				
					|  |  |  |                                     } | 
			
		
	
		
			
				
					|  |  |  |                                     }*/ | 
			
		
	
		
			
				
					|  |  |  |                                 } | 
			
		
	
		
			
				
					|  |  |  |                             } | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
	
		
			
				
					|  |  | @ -258,7 +289,7 @@ 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
 | 
			
		
	
		
			
				
					|  |  |  |                         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)); | 
			
		
	
	
		
			
				
					|  |  | @ -315,8 +346,8 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                         iv->setQueuedCmdFinished(); | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                     }*/ | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 yield(); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  | @ -327,6 +358,152 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |                 (mCbMiPayload)(val); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = 1) { | 
			
		
	
		
			
				
					|  |  |  |             record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the record structure
 | 
			
		
	
		
			
				
					|  |  |  |             rec->ts = mPayload[iv->id].ts; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             int8_t offset = -2; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             //iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (int)((p->packet[11+6] << 8) + p->packet[12+6])); // was 11/12, might be wrong!
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             //if (INV_TYPE_1CH == iv->type)
 | 
			
		
	
		
			
				
					|  |  |  |                 //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, (int)((p->packet[11+6] << 8) + p->packet[12+6]));
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[13] << 8) + p->packet[14]));
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (int)((p->packet[11+offset] << 8) + p->packet[12+offset])); | 
			
		
	
		
			
				
					|  |  |  |             if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ | 
			
		
	
		
			
				
					|  |  |  |                 iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(iv->alarmMesIndex)); | 
			
		
	
		
			
				
					|  |  |  |                 iv->enqueCommand<InfoCommand>(AlarmData); | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             /*    for decoding see
 | 
			
		
	
		
			
				
					|  |  |  |                 void MI600StsMsg (NRF24_packet_t *p){ | 
			
		
	
		
			
				
					|  |  |  |                   STAT = (int)((p->packet[11] << 8) + p->packet[12]); | 
			
		
	
		
			
				
					|  |  |  |                   FCNT = (int)((p->packet[13] << 8) + p->packet[14]); | 
			
		
	
		
			
				
					|  |  |  |                   FCODE = (int)((p->packet[15] << 8) + p->packet[16]); | 
			
		
	
		
			
				
					|  |  |  |                 #ifdef ESP8266 | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][5]=STAT; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][6]=FCNT; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][7]=FCODE; | 
			
		
	
		
			
				
					|  |  |  |                 #endif | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 */ | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         void miDataDecode(Inverter<> *iv, packet_t *p) { | 
			
		
	
		
			
				
					|  |  |  |             record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the parser
 | 
			
		
	
		
			
				
					|  |  |  |             rec->ts = mPayload[iv->id].ts; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             uint8_t chan = ( p->packet[2] == 0x89 || p->packet[2] == (0x36 + ALL_FRAMES) ) ? 1 : | 
			
		
	
		
			
				
					|  |  |  |                            ( p->packet[2] == 0x91 || p->packet[2] == (0x37 + ALL_FRAMES) ) ? 2 : | 
			
		
	
		
			
				
					|  |  |  |                            p->packet[2] == (0x38 + ALL_FRAMES) ? 3 : | 
			
		
	
		
			
				
					|  |  |  |                            4; | 
			
		
	
		
			
				
					|  |  |  |             int8_t offset = -2; | 
			
		
	
		
			
				
					|  |  |  |             // U_DC =  (float) ((p->packet[11] << 8) + p->packet[12])/10;
 | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(chan, FLD_UDC, rec), rec, (float)((p->packet[11+offset] << 8) + p->packet[12+offset])/10); | 
			
		
	
		
			
				
					|  |  |  |             yield(); | 
			
		
	
		
			
				
					|  |  |  |             // I_DC =  (float) ((p->packet[13] << 8) + p->packet[14])/10;
 | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(chan, FLD_IDC, rec), rec, (float)((p->packet[13+offset] << 8) + p->packet[14+offset])/10); | 
			
		
	
		
			
				
					|  |  |  |             yield(); | 
			
		
	
		
			
				
					|  |  |  |             //      U_AC =  (float) ((p->packet[15] << 8) + p->packet[16])/10;
 | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[15+offset] << 8) + p->packet[16+offset])/10); | 
			
		
	
		
			
				
					|  |  |  |             yield(); | 
			
		
	
		
			
				
					|  |  |  |             //      F_AC =  (float) ((p->packet[17] << 8) + p->packet[18])/100;
 | 
			
		
	
		
			
				
					|  |  |  |             //iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[17+offset] << 8) + p->packet[18+offset])/100);
 | 
			
		
	
		
			
				
					|  |  |  |             //yield();
 | 
			
		
	
		
			
				
					|  |  |  |             //      P_DC =  (float)((p->packet[19] << 8) + p->packet[20])/10;
 | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(chan, FLD_PDC, rec), rec, (float)((p->packet[19+offset] << 8) + p->packet[20+offset])/10); | 
			
		
	
		
			
				
					|  |  |  |             yield(); | 
			
		
	
		
			
				
					|  |  |  |             //      Q_DC =  (float)((p->packet[21] << 8) + p->packet[22])/1;
 | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(chan, FLD_Q, rec), rec, (float)((p->packet[21+offset] << 8) + p->packet[22+offset])/1); | 
			
		
	
		
			
				
					|  |  |  |             yield(); | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[23+offset] << 8) + p->packet[24+offset])/10); | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[17+offset] << 8) + p->packet[18+offset])/100); //23 is freq or IAC?
 | 
			
		
	
		
			
				
					|  |  |  |             yield(); | 
			
		
	
		
			
				
					|  |  |  |             //FLD_YD
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             if (p->packet[2] >= (0x36 + ALL_FRAMES) ) { | 
			
		
	
		
			
				
					|  |  |  |                 /*STAT = (uint8_t)(p->packet[25] );
 | 
			
		
	
		
			
				
					|  |  |  |                 FCNT = (uint8_t)(p->packet[26]); | 
			
		
	
		
			
				
					|  |  |  |                 FCODE = (uint8_t)(p->packet[27]); // MI300: (int)((p->packet[15] << 8) + p->packet[16]); */
 | 
			
		
	
		
			
				
					|  |  |  |                 //iv->setValue(iv->getPosByChFld(chan, FLD_YD, rec), rec, (uint8_t)(p->packet[25]));
 | 
			
		
	
		
			
				
					|  |  |  |                 //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (uint8_t)(p->packet[27]));
 | 
			
		
	
		
			
				
					|  |  |  |                 iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (uint8_t)(p->packet[21+offset])); | 
			
		
	
		
			
				
					|  |  |  |                 yield(); | 
			
		
	
		
			
				
					|  |  |  |                 if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ | 
			
		
	
		
			
				
					|  |  |  |                     iv->alarmMesIndex = rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                     DPRINTLN(DBG_INFO, "alarm ID incremented to " + String(iv->alarmMesIndex)); | 
			
		
	
		
			
				
					|  |  |  |                     iv->enqueCommand<InfoCommand>(AlarmData); | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0); // (getValue(iv->getPosByChFld(1, FLD_YD, rec), rec) + getValue(iv->getPosByChFld(2, FLD_YD, rec), rec)));
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                             iv->doCalculations(); | 
			
		
	
		
			
				
					|  |  |  |                             notify(mPayload[iv->id].txCmd); | 
			
		
	
		
			
				
					|  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |                             if(AlarmData == mPayload[iv->id].txCmd) { | 
			
		
	
		
			
				
					|  |  |  |                                 uint8_t i = 0; | 
			
		
	
		
			
				
					|  |  |  |                                 uint16_t code; | 
			
		
	
		
			
				
					|  |  |  |                                 uint32_t start, end; | 
			
		
	
		
			
				
					|  |  |  |                                 while(1) { | 
			
		
	
		
			
				
					|  |  |  |                                     code = iv->parseAlarmLog(i++, payload, payloadLen, &start, &end); | 
			
		
	
		
			
				
					|  |  |  |                                     if(0 == code) | 
			
		
	
		
			
				
					|  |  |  |                                         break; | 
			
		
	
		
			
				
					|  |  |  |                                     if (NULL != mCbMiAlarm) | 
			
		
	
		
			
				
					|  |  |  |                                         (mCbAlarm)(code, start, end); | 
			
		
	
		
			
				
					|  |  |  |                                     yield(); | 
			
		
	
		
			
				
					|  |  |  |                                 } | 
			
		
	
		
			
				
					|  |  |  |                             }*/ | 
			
		
	
		
			
				
					|  |  |  | /*decode here or memcopy payload for later decoding?
 | 
			
		
	
		
			
				
					|  |  |  |                 void MI600DataMsg(NRF24_packet_t *p){ | 
			
		
	
		
			
				
					|  |  |  |                   U_DC =  (float) ((p->packet[11] << 8) + p->packet[12])/10; | 
			
		
	
		
			
				
					|  |  |  |                   I_DC =  (float) ((p->packet[13] << 8) + p->packet[14])/10; | 
			
		
	
		
			
				
					|  |  |  |                   U_AC =  (float) ((p->packet[15] << 8) + p->packet[16])/10; | 
			
		
	
		
			
				
					|  |  |  |                   F_AC =  (float) ((p->packet[17] << 8) + p->packet[18])/100; | 
			
		
	
		
			
				
					|  |  |  |                   P_DC =  (float)((p->packet[19] << 8) + p->packet[20])/10; | 
			
		
	
		
			
				
					|  |  |  |                   Q_DC =  (float)((p->packet[21] << 8) + p->packet[22])/1; | 
			
		
	
		
			
				
					|  |  |  |                   TEMP =  (float) ((p->packet[23] << 8) + p->packet[24])/10;  //(int16_t)
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                   if ((30<U_DC<50) && (0<I_DC<15) && (200<U_AC<300) && (45<F_AC<55) && (0<P_DC<420) && (0<TEMP<80)) | 
			
		
	
		
			
				
					|  |  |  |                    DataOK = 1;  //we need to check this, if no crc
 | 
			
		
	
		
			
				
					|  |  |  |                   else { DEBUG_OUT.printf("Data Wrong!!\r\n");DataOK =0; return;} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                   if (p->packet[2] == 0x89)  {PV= 0; TotalP[1]=P_DC; pvCnt[0]=1;}//port 1
 | 
			
		
	
		
			
				
					|  |  |  |                   if (p->packet[2] == 0x91)  {PV= 1; TotalP[2]=P_DC; pvCnt[1]=1;}//port 2
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                   TotalP[0]=TotalP[1]+TotalP[2]+TotalP[3]+TotalP[4];//in TotalP[0] is the totalPV power
 | 
			
		
	
		
			
				
					|  |  |  |                   if((P_DC>400) || (P_DC<0) || (TotalP[0]>MAXPOWER)){// cant be!!
 | 
			
		
	
		
			
				
					|  |  |  |                     TotalP[0]=0; | 
			
		
	
		
			
				
					|  |  |  |                     return; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 #ifdef ESP8266 | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][0]=PV; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][1]=P_DC; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][2]=U_DC; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][3]=I_DC; | 
			
		
	
		
			
				
					|  |  |  |                   VALUES[PV][4]=Q_DC; | 
			
		
	
		
			
				
					|  |  |  |                 #endif | 
			
		
	
		
			
				
					|  |  |  |                   PMI=TotalP[0]; | 
			
		
	
		
			
				
					|  |  |  |                   LIM=(uint16_t)Limit; | 
			
		
	
		
			
				
					|  |  |  |                   PrintOutValues(); | 
			
		
	
		
			
				
					|  |  |  |                 }*/ | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |                 /*For MI1500:
 | 
			
		
	
		
			
				
					|  |  |  |                 if (MI1500) { | 
			
		
	
		
			
				
					|  |  |  |   STAT = (uint8_t)(p->packet[25] ); | 
			
		
	
		
			
				
					|  |  |  |   FCNT = (uint8_t)(p->packet[26]); | 
			
		
	
		
			
				
					|  |  |  |   FCODE = (uint8_t)(p->packet[27]); | 
			
		
	
		
			
				
					|  |  |  |   } | 
			
		
	
		
			
				
					|  |  |  |                 */ | 
			
		
	
		
			
				
					|  |  |  |                 DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": data msg ") + p->packet[0]); | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         bool build(uint8_t id, bool *complete) { | 
			
		
	
		
			
				
					|  |  |  |             /*DPRINTLN(DBG_VERBOSE, F("build"));
 | 
			
		
	
		
			
				
					|  |  |  |             uint16_t crc = 0xffff, crcRcv = 0x0000; | 
			
		
	
	
		
			
				
					|  |  | @ -362,9 +539,9 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |             memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); | 
			
		
	
		
			
				
					|  |  |  |             /*
 | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].gotFragment = false; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].retransmits = 0; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].maxPackId   = MAX_PAYLOAD_ENTRIES; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].lastFound   = false;*/ | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].retransmits = 0; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].complete    = false; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].txCmd       = 0; | 
			
		
	
		
			
				
					|  |  |  |             mPayload[id].requested   = false; | 
			
		
	
	
		
			
				
					|  |  | @ -381,6 +558,8 @@ class MiPayload { | 
			
		
	
		
			
				
					|  |  |  |         miPayload_t mPayload[MAX_NUM_INVERTERS]; | 
			
		
	
		
			
				
					|  |  |  |         bool mSerialDebug; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         Inverter<> *mHighPrioIv; | 
			
		
	
		
			
				
					|  |  |  |         alarmListenerType mCbMiAlarm; | 
			
		
	
		
			
				
					|  |  |  |         payloadListenerType mCbMiPayload; | 
			
		
	
		
			
				
					|  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | 
 |