|  | @ -18,11 +18,13 @@ typedef struct { | 
			
		
	
		
		
			
				
					|  |  |     uint8_t txCmd; |  |  |     uint8_t txCmd; | 
			
		
	
		
		
			
				
					|  |  |     uint8_t len[MAX_PAYLOAD_ENTRIES]; |  |  |     uint8_t len[MAX_PAYLOAD_ENTRIES]; | 
			
		
	
		
		
			
				
					|  |  |     bool complete; |  |  |     bool complete; | 
			
		
	
		
		
			
				
					
					|  |  |     bool stsa; |  |  |     bool dataAB[3]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |     bool stsb; |  |  |     bool stsAB[3]; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |     uint8_t sts[5]; | 
			
		
	
		
		
			
				
					|  |  |     uint8_t txId; |  |  |     uint8_t txId; | 
			
		
	
		
		
			
				
					|  |  |     uint8_t invId; |  |  |     uint8_t invId; | 
			
		
	
		
		
			
				
					|  |  |     uint8_t retransmits; |  |  |     uint8_t retransmits; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     bool gotFragment; | 
			
		
	
		
		
			
				
					|  |  |     /*
 |  |  |     /*
 | 
			
		
	
		
		
			
				
					|  |  |     uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; |  |  |     uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -65,6 +67,7 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |         void addAlarmListener(alarmListenerType cb) { |  |  |         void addAlarmListener(alarmListenerType cb) { | 
			
		
	
		
		
			
				
					|  |  |             mCbMiAlarm = cb; |  |  |             mCbMiAlarm = cb; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void loop() { |  |  |         void loop() { | 
			
		
	
		
		
			
				
					|  |  |             /*if(NULL != mHighPrioIv) {
 |  |  |             /*if(NULL != mHighPrioIv) {
 | 
			
		
	
		
		
			
				
					|  |  |                 iv->ivSend(mHighPrioIv, true); // should request firmware version etc.?
 |  |  |                 iv->ivSend(mHighPrioIv, true); // should request firmware version etc.?
 | 
			
		
	
	
		
		
			
				
					|  | @ -84,62 +87,108 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |             if (mSerialDebug) |  |  |             if (mSerialDebug) | 
			
		
	
		
		
			
				
					|  |  |                 DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX)); |  |  |                 DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") Requesting Inv SN ") + String(iv->config->serial.u64, HEX)); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             uint8_t cmd = iv->type == INV_TYPE_4CH ? 0x36 : 0x09; //iv->getQueuedCmd();
 |  |  |             uint8_t cmd = iv->getQueuedCmd(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd")); |  |  |             DPRINT(DBG_INFO, F("(#")); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); |  |  |             DBGPRINT(String(iv->id)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             DBGPRINT(F(") prepareDevInformCmd 0x")); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             DBGPRINTLN(String(cmd, HEX)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             uint8_t cmd2 = cmd; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if (cmd == 0x1 ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 cmd  = TX_REQ_INFO; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 cmd2 = 0x00; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             }; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd2, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
		
			
				
					|  |  |             mPayload[iv->id].txCmd = cmd; |  |  |             mPayload[iv->id].txCmd = cmd; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].dataAB[CH1] = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].stsAB[CH1] = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].dataAB[CH0] = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].stsAB[CH0] = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if (iv->type == INV_TYPE_2CH) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].dataAB[CH2] = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].stsAB[CH2] = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void add(Inverter<> *iv, packet_t *p) { |  |  |         void add(Inverter<> *iv, packet_t *p) { | 
			
		
	
		
		
			
				
					|  |  |             //DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX));
 |  |  |             //DPRINTLN(DBG_INFO, F("MI got data [0]=") + String(p->packet[0], HEX));
 | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             if (p->packet[0] == (0x08 + ALL_FRAMES)) { // 0x88; MI status response to 0x09
 |  |  |             if (p->packet[0] == (0x08 + ALL_FRAMES)) { // 0x88; MI status response to 0x09
 | 
			
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].stsa = true; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |                 miStsDecode(iv, p); |  |  |                 miStsDecode(iv, p); | 
			
		
	
		
		
			
				
					|  |  |             } else if (p->packet[0] == (0x11 + SINGLE_FRAME)) { // 0x92; MI status response to 0x11
 |  |  |             } else if (p->packet[0] == (0x11 + SINGLE_FRAME)) { // 0x92; MI status response to 0x11
 | 
			
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].stsb = true; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |                 miStsDecode(iv, p, CH2); |  |  |                 miStsDecode(iv, p, CH2); | 
			
		
	
		
		
			
				
					
					|  |  |             } else if (p->packet[0] == (0x09 + ALL_FRAMES)) { // MI data response to 0x09
 |  |  |             /*} else if (p->packet[0] == (0x09 + ALL_FRAMES)) { // MI data response to 0x09
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].txId = p->packet[0]; |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
		
			
				
					|  |  |                 miDataDecode(iv,p); |  |  |                 miDataDecode(iv,p); | 
			
		
	
		
		
			
				
					
					|  |  |                 iv->setQueuedCmdFinished(); |  |  |                 //iv->setQueuedCmdFinished();
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 if (INV_TYPE_2CH == iv->type) { |  |  |                 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); |  |  |                     //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?)
 |  |  |                 } else { // additional check for mPayload[iv->id].stsa == true might be a good idea (request retransmit?)
 | 
			
		
	
		
		
			
				
					|  |  |                     mPayload[iv->id].complete = true; |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
		
			
				
					|  |  |                     //iv->setQueuedCmdFinished();
 |  |  |                     //iv->setQueuedCmdFinished();
 | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             } else if (p->packet[0] == (0x11 + ALL_FRAMES)) { // MI data response to 0x11
 |  |  |             } else if (p->packet[0] == ()) { // MI data response to 0x11
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].txId = p->packet[0]; |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].complete = true; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |                 miDataDecode(iv,p); |  |  |                 miDataDecode(iv,p); | 
			
		
	
		
		
			
				
					
					|  |  |                 iv->setQueuedCmdFinished(); |  |  |                 mStat->rxSuccess++; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                 //iv->setQueuedCmdFinished();*/
 | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             } else if (p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME)) { // MI 1500 data response to 0x36, 0x37, 0x38 and 0x39
 |  |  |             } else if ( p->packet[0] == 0x09 + ALL_FRAMES || | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                         p->packet[0] == 0x11 + ALL_FRAMES || | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         ( p->packet[0] >= (0x36 + ALL_FRAMES) && p->packet[0] < (0x39 + SINGLE_FRAME) ) ) { // small MI or MI 1500 data responses to 0x09, 0x11, 0x36, 0x37, 0x38 and 0x39
 | 
			
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].txId = p->packet[0]; |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
		
			
				
					|  |  |                 miDataDecode(iv,p); |  |  |                 miDataDecode(iv,p); | 
			
		
	
		
		
			
				
					
					|  |  |                 iv->setQueuedCmdFinished(); |  |  |                 //mStat->rxSuccess++;
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 if (p->packet[0] < (0x39 + ALL_FRAMES)) { |  |  |                 //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); |  |  |                     //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 { |  |  |                 } else { | 
			
		
	
		
		
			
				
					|  |  |                     mPayload[iv->id].complete = true; |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
		
			
				
					|  |  |                     //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0);
 |  |  |                     //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, CALC_YD_CH0);
 | 
			
		
	
		
		
			
				
					|  |  |                     //iv->setQueuedCmdFinished();
 |  |  |                     //iv->setQueuedCmdFinished();
 | 
			
		
	
		
		
			
				
					
					|  |  |                 } |  |  |                 }*/ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             /*}
 |  |  |             //}
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } 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...
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             // for decoding see xls- Data collection instructions - #147ff
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /*
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  Polling the device software and hardware version number command | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  start byte	Command word	 routing address				 target address				 User data	 check	 end byte | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  byte[0]	 byte[1]	 byte[2]	 byte[3]	 byte[4]	 byte[5]	 byte[6]	 byte[7]	 byte[8]	 byte[9]	 byte[10]	 byte[11]	 byte[12] | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  0x7e	 0x0f	 xx	 xx	 xx	 xx	 YY	 YY	 YY	 YY	 0x00	 CRC	 0x7f | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  Command Receipt - First Frame | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  start byte	Command word	 target address				 routing address				 Multi-frame marking	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 check	 end byte | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  byte[0]	 byte[1]	 byte[2]	 byte[3]	 byte[4]	 byte[5]	 byte[6]	 byte[7]	 byte[8]	 byte[9]	 byte[10]	 byte[11]	 byte[12]	 byte[13]	 byte[14]	 byte[15]	 byte[16]	 byte[17]	 byte[18]	 byte[19]	 byte[20]	 byte[21]	 byte[22]	 byte[23]	 byte[24]	 byte[25]	 byte[26]	 byte[27]	 byte[28] | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  0x7e	 0x8f	 YY	 YY	 YY	 YY	 xx	 xx	 xx	 xx	 0x00	 USFWBuild_VER		 APPFWBuild_VER		 APPFWBuild_YYYY		 APPFWBuild_MMDD		 APPFWBuild_HHMM		 APPFW_PN				 HW_VER		 CRC	 0x7f | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  Command Receipt - Second Frame | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  start byte	Command word	 target address				 routing address				 Multi-frame marking	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 check	 end byte | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  byte[0]	 byte[1]	 byte[2]	 byte[3]	 byte[4]	 byte[5]	 byte[6]	 byte[7]	 byte[8]	 byte[9]	 byte[10]	 byte[11]	 byte[12]	 byte[13]	 byte[14]	 byte[15]	 byte[16]	 byte[17]	 byte[18]	 byte[19]	 byte[20]	 byte[21]	 byte[22]	 byte[23]	 byte[24]	 byte[25]	 byte[26]	 byte[27]	 byte[28] | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  0x7e	 0x8f	 YY	 YY	 YY	 YY	 xx	 xx	 xx	 xx	 0x01	 HW_PN				 HW_FB_TLmValue		 HW_FB_ReSPRT		 HW_GridSamp_ResValule		 HW_ECapValue		 Matching_APPFW_PN				 CRC	 0x7f | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  Command receipt - third frame | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  start byte	Command word	 target address				 routing address				 Multi-frame marking	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 User data	 check	 end byte | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  byte[0]	 byte[1]	 byte[2]	 byte[3]	 byte[4]	 byte[5]	 byte[6]	 byte[7]	 byte[8]	 byte[9]	 byte[10]	 byte[11]	 byte[12]	 byte[13]	 byte[14]	 byte[15]	 byte[16]	 byte[15]	 byte[16]	 byte[17]	 byte[18] | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  0x7e	 0x8f	 YY	 YY	 YY	 YY	 xx	 xx	 xx	 xx	 0x12	 APPFW_MINVER		 HWInfoAddr		 PNInfoCRC_gusv		 PNInfoCRC_gusv		 CRC	 0x7f | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             if (p->packet[0] == (TX_REQ_INFO + ALL_FRAMES)) {  // response from get information command
 |  |  | */ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 mPayload[iv->id].txId = p->packet[0]; |  |  |                 mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
		
			
				
					|  |  |                 DPRINTLN(DBG_DEBUG, F("Response from info request received")); |  |  |                 DPRINTLN(DBG_DEBUG, F("Response from info request received")); | 
			
		
	
		
		
			
				
					|  |  |                 uint8_t *pid = &p->packet[9]; |  |  |                 uint8_t *pid = &p->packet[9]; | 
			
		
	
		
		
			
				
					|  |  |                 if (*pid == 0x00) { |  |  |                 if (*pid == 0x00) { | 
			
		
	
		
		
			
				
					
					|  |  |                     DPRINT(DBG_DEBUG, F("fragment number zero received and ignored")); |  |  |                     DPRINT(DBG_DEBUG, F("fragment number zero received")); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 } else { |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                     iv->setQueuedCmdFinished(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 } //else {
 | 
			
		
	
		
		
			
				
					|  |  |                     DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); |  |  |                     DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     /*
 | 
			
		
	
		
		
			
				
					|  |  |                     if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { |  |  |                     if ((*pid & 0x7F) < MAX_PAYLOAD_ENTRIES) { | 
			
		
	
		
		
			
				
					|  |  |                         memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); |  |  |                         memcpy(mPayload[iv->id].data[(*pid & 0x7F) - 1], &p->packet[10], p->len - 11); | 
			
		
	
		
		
			
				
					|  |  |                         mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; |  |  |                         mPayload[iv->id].len[(*pid & 0x7F) - 1] = p->len - 11; | 
			
		
	
	
		
		
			
				
					|  | @ -242,13 +291,21 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |                 if (IV_HM == iv->ivGen) // only process MI inverters
 |  |  |                 if (IV_HM == iv->ivGen) // only process MI inverters
 | 
			
		
	
		
		
			
				
					|  |  |                     continue; // skip to next inverter
 |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                 /*if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && (0 != mPayload[iv->id].txId)) {
 |  |  |                 if ((mPayload[iv->id].txId != (TX_REQ_INFO + ALL_FRAMES)) && | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                     // no processing needed if txId is not 0x95
 |  |  |                     (mPayload[iv->id].txId <  (0x36 + ALL_FRAMES)) && | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                     (mPayload[iv->id].txId >  (0x39 + ALL_FRAMES)) && | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     (mPayload[iv->id].txId != (0x09 + ALL_FRAMES)) && | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     (mPayload[iv->id].txId != (0x11 + ALL_FRAMES)) && | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     (mPayload[iv->id].txId != (0x88)) && | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     (mPayload[iv->id].txId != (0x92)) && | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     (mPayload[iv->id].txId != 0 )) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     // no processing needed if txId is not one of 0x95, 0x88, 0x89, 0x91, 0x92 or resonse to 0x36ff
 | 
			
		
	
		
		
			
				
					|  |  |                     mPayload[iv->id].complete = true; |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
		
			
				
					|  |  |                     continue; // skip to next inverter
 |  |  |                     continue; // skip to next inverter
 | 
			
		
	
		
		
			
				
					
					|  |  |                 }*/ |  |  |                 } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                 if (!mPayload[iv->id].complete) { |  |  |                 if (!mPayload[iv->id].complete) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     //DPRINTLN(DBG_INFO, F("Pyld incompl code")); //info for testing only
 | 
			
		
	
		
		
			
				
					|  |  |                     bool crcPass, pyldComplete; |  |  |                     bool crcPass, pyldComplete; | 
			
		
	
		
		
			
				
					|  |  |                     crcPass = build(iv->id, &pyldComplete); |  |  |                     crcPass = build(iv->id, &pyldComplete); | 
			
		
	
		
		
			
				
					|  |  |                     if (!crcPass && !pyldComplete) { // payload not complete
 |  |  |                     if (!crcPass && !pyldComplete) { // payload not complete
 | 
			
		
	
	
		
		
			
				
					|  | @ -263,21 +320,32 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |                             } else { |  |  |                             } else { | 
			
		
	
		
		
			
				
					|  |  |                                 if (mPayload[iv->id].retransmits < mMaxRetrans) { |  |  |                                 if (mPayload[iv->id].retransmits < mMaxRetrans) { | 
			
		
	
		
		
			
				
					|  |  |                                     mPayload[iv->id].retransmits++; |  |  |                                     mPayload[iv->id].retransmits++; | 
			
		
	
		
		
			
				
					
					|  |  |                                     //mSys->Radio.prepareDevInformCmd(iv->radioId.u64, iv->getQueuedCmd(), mPayload[iv->id].ts, iv->alarmMesIndex, false, 0x11);
 |  |  |                                     if( !mPayload[iv->id].gotFragment ) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                     mSys->Radio.sendCmdPacket(iv->radioId.u64, iv->getQueuedCmd(), 24, true); |  |  |                                         DPRINT(DBG_INFO, F("(#")); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                     /*if(false == mPayload[iv->id].gotFragment) {
 |  |  |                                         DBGPRINT(String(iv->id)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                         DPRINTLN(DBG_WARN, F("(#") + String(iv->id) + F(") nothing received")); |  |  |                                         DBGPRINTLN(F(") nothing received")); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                                         mPayload[iv->id].retransmits = mMaxRetrans; |  |  |                                         mPayload[iv->id].retransmits = mMaxRetrans; | 
			
		
	
		
		
			
				
					|  |  |                                     } else { |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |                                         for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { |  |  |                                         uint8_t cmd = mPayload[iv->id].txCmd; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                             if (mPayload[iv->id].len[i] == 0) { |  |  |                                         if ( cmd >= 0x36 && cmd < 0x39 ) { // MI-1500 Data command
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                                 DPRINTLN(DBG_WARN, F("Frame ") + String(i + 1) + F(" missing: Request Retransmit")); |  |  |                                             cmd++; // just request the next channel
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                                 mSys->Radio.sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); |  |  |                                         } else if ( cmd == 0x09 ) {//MI single or dual channel device
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                                 break;  // only request retransmit one frame per loop
 |  |  |                                             if ( mPayload[iv->id].dataAB[CH1] && iv->type == INV_TYPE_2CH  ) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                                             } |  |  |                                                 if (!mPayload[iv->id].stsAB[CH2] || !mPayload[iv->id].dataAB[CH2] ) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                                                     cmd = 0x11; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         } else if ( cmd == 0x11) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             if ( mPayload[iv->id].dataAB[CH2] ) { // data is there, but no status
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                                 if (!mPayload[iv->id].stsAB[CH1] || !mPayload[iv->id].dataAB[CH1] ) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                                     cmd = 0x09; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") next request is 0x") + String(cmd, HEX)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         //mSys->Radio.sendCmdPacket(iv->radioId.u64, cmd, cmd, true);
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, true, cmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                                         mPayload[iv->id].txCmd = cmd; | 
			
		
	
		
		
			
				
					|  |  |                                         yield(); |  |  |                                         yield(); | 
			
		
	
		
		
			
				
					|  |  |                                     } |  |  |                                     } | 
			
		
	
		
		
			
				
					|  |  |                                     }*/ |  |  |  | 
			
		
	
		
		
			
				
					|  |  |                                 } |  |  |                                 } | 
			
		
	
		
		
			
				
					|  |  |                             } |  |  |                             } | 
			
		
	
		
		
			
				
					|  |  |                         } |  |  |                         } | 
			
		
	
	
		
		
			
				
					|  | @ -289,14 +357,25 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |                             DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") prepareDevInformCmd 0x") + String(mPayload[iv->id].txCmd, HEX)); |  |  |                             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); |  |  |                             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: cmd:  0x") + String(mPayload[iv->id].txCmd, HEX)); | 
			
		
	
		
		
			
				
					|  |  |                         DPRINTLN(DBG_INFO, F("procPyld: txid: 0x") + String(mPayload[iv->id].txId, 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)); |  |  |                         //DPRINTLN(DBG_DEBUG, F("procPyld: max:  ") + String(mPayload[iv->id].maxPackId));
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                         record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd);  // choose the parser
 |  |  |                         //record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd);  // choose the parser
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                         mPayload[iv->id].complete = true; |  |  |                         mPayload[iv->id].complete = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         uint8_t ac_pow = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         //if (mPayload[iv->id].sts[0] == 3) {
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             ac_pow = calcPowerDcCh0(iv, 0)*9.5; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         //}
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the parser
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         iv->setValue(iv->getPosByChFld(0, FLD_PAC, rec), rec, (float) (ac_pow/10)); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                         uint8_t payload[128]; |  |  |                         DPRINTLN(DBG_INFO, F("proces: compl. set of msgs detected")); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                         iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         iv->doCalculations(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         /*uint8_t payload[128];
 | 
			
		
	
		
		
			
				
					|  |  |                         uint8_t payloadLen = 0; |  |  |                         uint8_t payloadLen = 0; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |                         memset(payload, 0, 128); |  |  |                         memset(payload, 0, 128); | 
			
		
	
	
		
		
			
				
					|  | @ -345,8 +424,8 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |                             mStat->rxFail++; |  |  |                             mStat->rxFail++; | 
			
		
	
		
		
			
				
					|  |  |                         } |  |  |                         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |                         iv->setQueuedCmdFinished(); |  |  |                         iv->setQueuedCmdFinished(); */ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                     }*/ |  |  |                     } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |                 yield(); |  |  |                 yield(); | 
			
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
	
		
		
			
				
					|  | @ -359,96 +438,159 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = CH1) { |  |  |         void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t chan = CH1) { | 
			
		
	
		
		
			
				
					
					|  |  |             DPRINTLN(DBG_INFO, F("Inverter ") + String(iv->id) + F(": status msg 0x") + String(p->packet[0], HEX)); |  |  |             DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") status msg 0x") + String(p->packet[0], HEX)); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the record structure
 |  |  |             record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the record structure
 | 
			
		
	
		
		
			
				
					|  |  |             rec->ts = mPayload[iv->id].ts; |  |  |             rec->ts = mPayload[iv->id].ts; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[iv->id].gotFragment = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[iv->id].txId = p->packet[0]; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             //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!
 |  |  |             uint8_t status  = (p->packet[11] << 8) + p->packet[12]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  |             uint8_t stschan = p->packet[0] == 0x88 ? CH1 : CH2; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //if (INV_TYPE_1CH == iv->type)
 |  |  |             mPayload[iv->id].sts[stschan] = status; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 //iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, (int)((p->packet[11+6] << 8) + p->packet[12+6]));
 |  |  |             mPayload[iv->id].stsAB[stschan] = true; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             if (mPayload[iv->id].stsAB[CH1] && mPayload[iv->id].stsAB[CH2]) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].stsAB[CH0] = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if ( !mPayload[iv->id].sts[0] || status < mPayload[iv->id].sts[0]) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].sts[0] = status; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, status); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             //iv->setValue(iv->getPosByChFld(chan, FLD_EVT, rec), rec, (int)((p->packet[13] << 8) + p->packet[14]));
 |  |  |             /*if ( !mPayload[iv->id].dataAB[0] || !mPayload[iv->id].dataAB[1] ) {
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                 uint8_t cmd = mPayload[iv->id].dataAB[0] ? 0x11 : 0x09; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 DPRINTLN(DBG_INFO, F("request missing status 0x") + String(cmd, HEX)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].txCmd = cmd; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 rem: gotFragment should be a better solution | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } */ | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (int)((p->packet[11] << 8) + p->packet[12])); |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             //iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (int)((p->packet[14] << 8) + p->packet[16]));
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ |  |  |             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?!?
 |  |  |                 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, "alarm ID incremented to " + String(iv->alarmMesIndex)); | 
			
		
	
		
		
			
				
					|  |  |                 iv->enqueCommand<InfoCommand>(AlarmData); |  |  |                 iv->enqueCommand<InfoCommand>(AlarmData); | 
			
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |             /* Unclear how in HM inverters Info and alarm data is handled...
 |  |  |             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")); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  |                 iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             /*            int8_t offset = -2;
 |  |  |                 iv->setQueuedCmdFinished(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  |                 iv->doCalculations(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 for decoding see |  |  |                 notify(mPayload[iv->id].txCmd); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |                 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 |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |                 */ |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void miDataDecode(Inverter<> *iv, packet_t *p) { |  |  |         void miDataDecode(Inverter<> *iv, packet_t *p) { | 
			
		
	
		
		
			
				
					|  |  |             record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the parser
 |  |  |             record_t<> *rec = iv->getRecordStruct(RealTimeRunData_Debug);  // choose the parser
 | 
			
		
	
		
		
			
				
					|  |  |             rec->ts = mPayload[iv->id].ts; |  |  |             rec->ts = mPayload[iv->id].ts; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[iv->id].gotFragment = true; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             uint8_t datachan = ( p->packet[0] == 0x89 || p->packet[0] == (0x36 + ALL_FRAMES) ) ? CH1 : |  |  |             uint8_t datachan = ( p->packet[0] == 0x89 || p->packet[0] == (0x36 + ALL_FRAMES) ) ? CH1 : | 
			
		
	
		
		
			
				
					|  |  |                            ( p->packet[0] == 0x91 || p->packet[0] == (0x37 + ALL_FRAMES) ) ? CH2 : |  |  |                            ( p->packet[0] == 0x91 || p->packet[0] == (0x37 + ALL_FRAMES) ) ? CH2 : | 
			
		
	
		
		
			
				
					|  |  |                            p->packet[0] == (0x38 + ALL_FRAMES) ? CH3 : |  |  |                            p->packet[0] == (0x38 + ALL_FRAMES) ? CH3 : | 
			
		
	
		
		
			
				
					|  |  |                            CH4; |  |  |                            CH4; | 
			
		
	
		
		
			
				
					
					|  |  |             int8_t offset = -2; |  |  |             DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") data msg 0x") + String(p->packet[0], HEX) + F(" channel ") + datachan); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             // U_DC =  (float) ((p->packet[11] << 8) + p->packet[12])/10;
 |  |  |             // count in RF_communication_protocol.xlsx is with offset = -1
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_UDC, rec), rec, (float)((p->packet[11+offset] << 8) + p->packet[12+offset])/10); |  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_UDC, rec), rec, (float)((p->packet[9] << 8) + p->packet[10])/10); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |             yield(); |  |  |             yield(); | 
			
		
	
		
		
			
				
					
					|  |  |             // I_DC =  (float) ((p->packet[13] << 8) + p->packet[14])/10;
 |  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_IDC, rec), rec, (float)((p->packet[11] << 8) + p->packet[12])/10); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_IDC, rec), rec, (float)((p->packet[13+offset] << 8) + p->packet[14+offset])/10); |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  |             yield(); |  |  |             yield(); | 
			
		
	
		
		
			
				
					
					|  |  |             //      U_AC =  (float) ((p->packet[15] << 8) + p->packet[16])/10;
 |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[13] << 8) + p->packet[14])/10); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(0, FLD_UAC, rec), rec, (float)((p->packet[15+offset] << 8) + p->packet[16+offset])/10); |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  |             yield(); |  |  |             yield(); | 
			
		
	
		
		
			
				
					
					|  |  |             //      F_AC =  (float) ((p->packet[17] << 8) + p->packet[18])/100;
 |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[15] << 8) + p->packet[16])/100); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //iv->setValue(iv->getPosByChFld(0, FLD_IAC, rec), rec, (float)((p->packet[17+offset] << 8) + p->packet[18+offset])/100);
 |  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_PDC, rec), rec, (float)((p->packet[17] << 8) + p->packet[18])/10); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |             //yield();
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             //      P_DC =  (float)((p->packet[19] << 8) + p->packet[20])/10;
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_PDC, rec), rec, (float)((p->packet[19+offset] << 8) + p->packet[20+offset])/10); |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |             yield(); |  |  |             yield(); | 
			
		
	
		
		
			
				
					
					|  |  |             //      Q_DC =  (float)((p->packet[21] << 8) + p->packet[22])/1;
 |  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_YD, rec), rec, (float)((p->packet[19] << 8) + p->packet[20])/1); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(datachan, FLD_YD, rec), rec, (float)((p->packet[21+offset] << 8) + p->packet[22+offset])/1); |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  |             yield(); |  |  |             yield(); | 
			
		
	
		
		
			
				
					
					|  |  |             iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[23+offset] << 8) + p->packet[24+offset])/10); //23 is freq or IAC?
 |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_T, rec), rec, (float) ((int16_t)(p->packet[21] << 8) + p->packet[22])/10); | 
			
				
				
			
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(0, FLD_F, rec), rec, (float) ((p->packet[17+offset] << 8) + p->packet[18+offset])/100); |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  |             iv->setValue(iv->getPosByChFld(0, FLD_IRR, rec), rec, (float) (calcIrradiation(iv, datachan))); |  |  |             iv->setValue(iv->getPosByChFld(0, FLD_IRR, rec), rec, (float) (calcIrradiation(iv, datachan))); | 
			
		
	
		
		
			
				
					
					|  |  |             yield(); |  |  |             //AC Power is missing; we may have to calculate, as no respective data is in payload
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             //FLD_YD
 |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             if ( datachan < 3 ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].dataAB[datachan] = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if ( !mPayload[iv->id].dataAB[CH0] && mPayload[iv->id].dataAB[CH2] && mPayload[iv->id].dataAB[CH2] ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].dataAB[CH0] = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             if (p->packet[0] >= (0x36 + ALL_FRAMES) ) { |  |  |             if (p->packet[0] >= (0x36 + ALL_FRAMES) ) { | 
			
		
	
		
		
			
				
					
					|  |  |                 /*status message analysis most liklely needs to be changed, see MiStsMst*/ |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 /*STAT = (uint8_t)(p->packet[25] );
 |  |  |                 /*For MI1500:
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                 if (MI1500) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                   STAT = (uint8_t)(p->packet[25] ); | 
			
		
	
		
		
			
				
					|  |  |                   FCNT = (uint8_t)(p->packet[26]); |  |  |                   FCNT = (uint8_t)(p->packet[26]); | 
			
		
	
		
		
			
				
					
					|  |  |                 FCODE = (uint8_t)(p->packet[27]); // MI300/Mi600 stsMsg:: (int)((p->packet[15] << 8) + p->packet[16]); */
 |  |  |                   FCODE = (uint8_t)(p->packet[27]); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, (uint8_t)(p->packet[25+offset])); |  |  |                 }*/ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 yield(); |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |                 uint8_t status = (uint8_t)(p->packet[23]); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].sts[datachan] = status; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 if ( !mPayload[iv->id].sts[0] || status < mPayload[iv->id].sts[0]) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mPayload[iv->id].sts[0] = status; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, status); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 if (p->packet[0] < (0x39 + ALL_FRAMES) ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     /*uint8_t cmd = p->packet[0] - ALL_FRAMES + 1;
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mPayload[iv->id].txCmd = cmd;*/ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mPayload[iv->id].complete = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 else if (p->packet[0] == (0x39 + ALL_FRAMES) ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     /*uint8_t cmd = p->packet[0] - ALL_FRAMES + 1;
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mPayload[iv->id].txCmd = cmd;*/ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mPayload[iv->id].complete = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 //iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, calcMiSts(iv));yield();
 | 
			
		
	
		
		
			
				
					|  |  |                 if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ |  |  |                 if (iv->alarmMesIndex < rec->record[iv->getPosByChFld(0, FLD_EVT, rec)]){ | 
			
		
	
		
		
			
				
					|  |  |                     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)); |  |  |                     DPRINTLN(DBG_INFO, F("alarm ID incremented to ") + String(iv->alarmMesIndex)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                     iv->enqueCommand<InfoCommand>(AlarmData); |  |  |                     //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->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); //datachan));
 |  |  |             //preliminary AC calculation...
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             uint8_t ac_pow = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             //if (mPayload[iv->id].sts[0] == 3) {
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 ac_pow = calcPowerDcCh0(iv, 0)*9.5; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             //}
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             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
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                  && mPayload[iv->id].dataAB[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")); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     iv->setValue(iv->getPosByChFld(0, FLD_YD, rec), rec, calcYieldDayCh0(iv,0)); | 
			
		
	
		
		
			
				
					|  |  |                     iv->doCalculations(); |  |  |                     iv->doCalculations(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 /*} else {
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     //retry to get missing status info for one or two channel devices
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     DPRINTLN(DBG_INFO, F("request missing data or status 0x") + String(cmd, HEX)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     mPayload[iv->id].txCmd = cmd; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     //iv->enqueCommand(cmd); // mPayload[iv->id].dataAB[1] ? 0x09 : 0x11)
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 }*/ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             /* should be included in process()
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             else if (mPayload[iv->id].txCmd == 0x09 && iv->type == INV_TYPE_2CH) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 uint8_t cmd = 0x11; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 DPRINTLN(DBG_INFO, F("request second data channel 0x") + String(cmd, HEX)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false, cmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].txCmd = cmd; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].complete = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             }*/ | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             iv->setQueuedCmdFinished(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mStat->rxSuccess++; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             yield(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             notify(mPayload[iv->id].txCmd); |  |  |             notify(mPayload[iv->id].txCmd); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | /*
 |  |  | /*
 | 
			
		
	
		
		
			
				
					|  |  |                             if(AlarmData == mPayload[iv->id].txCmd) { |  |  |                             if(AlarmData == mPayload[iv->id].txCmd) { | 
			
		
	
		
		
			
				
					|  |  |                                 uint8_t i = 0; |  |  |                                 uint8_t i = 0; | 
			
		
	
	
		
		
			
				
					|  | @ -463,66 +605,26 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |                                     yield(); |  |  |                                     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 0x") + String(p->packet[0], HEX) + F(" channel ") + datachan); |  |  |  | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         bool build(uint8_t id, bool *complete) { |  |  |         bool build(uint8_t id, bool *complete) { | 
			
		
	
		
		
			
				
					
					|  |  |             /*DPRINTLN(DBG_VERBOSE, F("build"));
 |  |  |             DPRINTLN(DBG_VERBOSE, F("build")); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             uint16_t crc = 0xffff, crcRcv = 0x0000; |  |  |             /*uint16_t crc = 0xffff, crcRcv = 0x0000;
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |             if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) |  |  |             if (mPayload[id].maxPackId > MAX_PAYLOAD_ENTRIES) | 
			
		
	
		
		
			
				
					|  |  |                 mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; |  |  |                 mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; | 
			
		
	
		
		
			
				
					
					|  |  | 
 |  |  |             */ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             // check if all fragments are there
 |  |  |             // check if all messages are there
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             *complete = true; |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { |  |  |             *complete = mPayload[id].complete; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                 if(mPayload[id].len[i] == 0) |  |  |             uint8_t txCmd = mPayload[id].txCmd; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |                     *complete = false; |  |  |             //uint8_t cmd = getQueuedCmd();
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             } |  |  |             if(!*complete) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             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 ) | 
			
		
	
		
		
			
				
					|  |  |                     return false; |  |  |                     return false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |             for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { |  |  |             /*for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) {
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                 if (mPayload[id].len[i] > 0) { |  |  |                 if (mPayload[id].len[i] > 0) { | 
			
		
	
		
		
			
				
					|  |  |                     if (i == (mPayload[id].maxPackId - 1)) { |  |  |                     if (i == (mPayload[id].maxPackId - 1)) { | 
			
		
	
		
		
			
				
					|  |  |                         crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc); |  |  |                         crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc); | 
			
		
	
	
		
		
			
				
					|  | @ -538,21 +640,53 @@ class MiPayload { | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         void reset(uint8_t id) { |  |  |         void reset(uint8_t id) { | 
			
		
	
		
		
			
				
					
					|  |  |             DPRINTLN(DBG_INFO, "resetPayload: id: " + String(id)); |  |  |             DPRINTLN(DBG_INFO, F("resetPayload: id: ") + String(id)); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); |  |  |             memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); | 
			
		
	
		
		
			
				
					|  |  |             /*
 |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             mPayload[id].gotFragment = false; |  |  |             mPayload[id].gotFragment = false; | 
			
		
	
		
		
			
				
					
					|  |  |             mPayload[id].maxPackId   = MAX_PAYLOAD_ENTRIES; |  |  |             /*mPayload[id].maxPackId   = MAX_PAYLOAD_ENTRIES;
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             mPayload[id].lastFound   = false;*/ |  |  |             mPayload[id].lastFound   = false;*/ | 
			
		
	
		
		
			
				
					|  |  |             mPayload[id].retransmits = 0; |  |  |             mPayload[id].retransmits = 0; | 
			
		
	
		
		
			
				
					|  |  |             mPayload[id].complete    = false; |  |  |             mPayload[id].complete    = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].dataAB[CH0] = true; //required for 1CH and 2CH devices
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].dataAB[CH1] = true; //required for 1CH and 2CH devices
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].dataAB[CH2] = true; //only required for 2CH devices
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].stsAB[CH0]  = true; //required for 1CH and 2CH devices
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             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].txCmd       = 0; | 
			
		
	
		
		
			
				
					|  |  |             mPayload[id].requested   = false; |  |  |             mPayload[id].requested   = false; | 
			
		
	
		
		
			
				
					|  |  |             mPayload[id].ts          = *mTimestamp; |  |  |             mPayload[id].ts          = *mTimestamp; | 
			
		
	
		
		
			
				
					
					|  |  |             mPayload[id].stsa        = false; |  |  |             mPayload[id].sts[0]      = 0; //disable this in case gotFragment is not working
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             mPayload[id].stsb        = false; |  |  |             mPayload[id].sts[CH1]    = 0; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].sts[CH2]    = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].sts[CH3]    = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             mPayload[id].sts[CH4]    = 0; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /*        template<class T=uint8_t>
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         static T calcMiSts(Inverter<> *iv) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             if(NULL != iv) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 T result = 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 bool stsComplete = true; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 uint8_t stsCh; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 for(uint8_t i = 1; i <= iv->channels; i++) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     stsCh = mPayload[iv->id].sts[i]; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     if (!stsCh) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         stsComplete = false; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     } else if ( !result || stsCh < result ) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         result = stsCh; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         if (stsComplete && stsCh > stsComplete) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                             stsComplete = stsCh; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 mPayload[iv->id].sts[0] = stsComplete; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 return result; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             return 0; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         IApp *mApp; |  |  |         IApp *mApp; | 
			
		
	
		
		
			
				
					|  |  |         HMSYSTEM *mSys; |  |  |         HMSYSTEM *mSys; | 
			
		
	
		
		
			
				
					|  |  |         statistics_t *mStat; |  |  |         statistics_t *mStat; | 
			
		
	
	
		
		
			
				
					|  | 
 |