@ -15,16 +15,17 @@
typedef struct {
uint32_t ts ;
bool requested ;
bool limitrequested ;
uint8_t txCmd ;
uint8_t len [ MAX_PAYLOAD_ENTRIES ] ;
bool complete ;
bool dataAB [ 3 ] ;
bool stsAB [ 3 ] ;
uint8_t sts [ 5 ] ;
uint16_t sts [ 6 ] ;
uint8_t txId ;
uint8_t invId ;
uint8_t retransmits ;
uint8_t skipfirstrepeat ;
//uint8_t skipfirstrepeat;
bool gotFragment ;
/*
uint8_t data [ MAX_PAYLOAD_ENTRIES ] [ MAX_RF_PAYLOAD_SIZE ] ;
@ -48,7 +49,8 @@ class MiPayload {
mMaxRetrans = maxRetransmits ;
mTimestamp = timestamp ;
for ( uint8_t i = 0 ; i < MAX_NUM_INVERTERS ; i + + ) {
reset ( i ) ;
reset ( i , true ) ;
mPayload [ i ] . limitrequested = true ;
}
mSerialDebug = false ;
mHighPrioIv = NULL ;
@ -68,55 +70,106 @@ class MiPayload {
}
void loop ( ) {
/*if(NULL != mHighPrioIv ) {
iv - > iv Send( mHighPrioIv , true ) ; // should request firmware version etc. ?
if ( NULL ! = mHighPrioIv ) { // && mHighPrioIv->ivGen == IV_MI ) {
ivSend ( mHighPrioIv , true ) ; // for devcontrol commands ?
mHighPrioIv = NULL ;
} */
}
}
void ivSendHighPrio ( Inverter < > * iv ) {
mHighPrioIv = iv ;
}
void ivSend ( Inverter < > * iv ) {
void ivSend ( Inverter < > * iv , bool highPrio = false ) {
if ( ! highPrio ) {
if ( mPayload [ iv - > id ] . requested ) {
if ( ! mPayload [ iv - > id ] . complete )
process ( false ) ; // no retransmit
if ( ! mPayload [ iv - > id ] . complete ) {
if ( ! mPayload [ iv - > id ] . gotFragment )
mStat - > rxFailNoAnser + + ; // got nothing
else
mStat - > rxFail + + ; // got fragments but not complete response
iv - > setQueuedCmdFinished ( ) ; // command failed
if ( mSerialDebug )
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINTLN ( F ( " enqueued cmd failed/timeout " ) ) ;
if ( mSerialDebug ) {
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " no Payload received! (retransmits: " ) ) ;
DBGPRINT ( String ( mPayload [ iv - > id ] . retransmits ) ) ;
DBGPRINTLN ( F ( " ) " ) ) ;
}
}
}
}
reset ( iv - > id ) ;
mPayload [ iv - > id ] . requested = true ;
yield ( ) ;
if ( mSerialDebug )
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) Requesting Inv SN " ) + String ( iv - > config - > serial . u64 , HEX ) ) ;
uint8_t cmd = iv - > getQueuedCmd ( ) ;
DPRINT ( DBG_INFO , F ( " (# " ) ) ;
DBGPRINT ( String ( iv - > id ) ) ;
DBGPRINT ( F ( " ) prepareDevInformCmd 0x " ) ) ;
DBGPRINTLN ( String ( cmd , HEX ) ) ;
uint8_t cmd2 = cmd ;
if ( cmd = = 0x1 ) { //0x1
cmd = 0x0f ;
cmd2 = 0x00 ;
mSys - > Radio . sendCmdPacket ( iv - > radioId . u64 , cmd , cmd2 , false ) ;
} else {
mSys - > Radio . prepareDevInformCmd ( iv - > radioId . u64 , cmd2 , mPayload [ iv - > id ] . ts , iv - > alarmMesIndex , false , cmd ) ;
} ;
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 ( mSerialDebug ) {
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " Requesting Inv SN " ) ) ;
DBGPRINTLN ( String ( iv - > config - > serial . u64 , HEX ) ) ;
}
if ( iv - > type = = INV_TYPE_2CH ) {
mPayload [ iv - > id ] . dataAB [ CH2 ] = false ;
mPayload [ iv - > id ] . stsAB [ CH2 ] = false ;
if ( iv - > getDevControlRequest ( ) ) {
if ( mSerialDebug ) {
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " Devcontrol request 0x " ) ) ;
DHEX ( iv - > devControlCmd ) ;
DBGPRINT ( F ( " power limit " ) ) ;
DBGPRINTLN ( String ( iv - > powerLimit [ 0 ] ) ) ;
}
mSys - > Radio . sendControlPacket ( iv - > radioId . u64 , iv - > devControlCmd , iv - > powerLimit , false , false ) ;
mPayload [ iv - > id ] . txCmd = iv - > devControlCmd ;
mPayload [ iv - > id ] . limitrequested = true ;
iv - > clearCmdQueue ( ) ;
iv - > enqueCommand < InfoCommand > ( SystemConfigPara ) ; // try to read back power limit
} else {
uint8_t cmd = iv - > getQueuedCmd ( ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " prepareDevInformCmd 0x " ) ) ;
DBGHEXLN ( cmd ) ;
uint8_t cmd2 = cmd ;
if ( cmd = = SystemConfigPara ) { //0x05 for HM-types
if ( ! mPayload [ iv - > id ] . limitrequested ) { // only do once at startup
iv - > setQueuedCmdFinished ( ) ;
cmd = iv - > getQueuedCmd ( ) ;
} else {
mPayload [ iv - > id ] . limitrequested = false ;
}
}
if ( cmd = = 0x01 | | cmd = = SystemConfigPara ) { //0x1 and 0x05 for HM-types
cmd = 0x0f ; // for MI, these seem to make part of the Polling the device software and hardware version number command
cmd2 = cmd = = SystemConfigPara ? 0x01 : 0x00 ; //perhaps we can only try to get second frame?
mSys - > Radio . sendCmdPacket ( iv - > radioId . u64 , cmd , cmd2 , false ) ;
} else {
mSys - > Radio . prepareDevInformCmd ( iv - > radioId . u64 , cmd2 , mPayload [ iv - > id ] . ts , iv - > alarmMesIndex , false , cmd ) ;
} ;
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 ) {
//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
miStsDecode ( iv , p ) ;
}
@ -127,7 +180,8 @@ class MiPayload {
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
( p - > packet [ 0 ] > = ( 0x36 + ALL_FRAMES ) & & p - > packet [ 0 ] < ( 0x39 + SINGLE_FRAME )
& & mPayload [ iv - > id ] . txCmd ! = 0x0f ) ) { // small MI or MI 1500 data responses to 0x09, 0x11, 0x36, 0x37, 0x38 and 0x39
mPayload [ iv - > id ] . txId = p - > packet [ 0 ] ;
miDataDecode ( iv , p ) ;
}
@ -177,30 +231,65 @@ const byteAssign_t InfoAssignment[] = {
for ( uint8_t i = 0 ; i < 5 ; i + + ) {
iv - > setValue ( i , rec , ( float ) ( ( p - > packet [ ( 12 + 2 * i ) ] < < 8 ) + p - > packet [ ( 13 + 2 * i ) ] ) / 1 ) ;
}
iv - > isConnected = true ;
if ( mSerialDebug ) {
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DPRINT ( DBG_INFO , F ( " HW_VER is " ) ) ;
DBGPRINTLN ( String ( ( p - > packet [ 24 ] < < 8 ) + p - > packet [ 25 ] ) ) ;
}
/*iv->setQueuedCmdFinished();
mSys - > Radio . sendCmdPacket ( iv - > radioId . u64 , 0x0f , 0x01 , false ) ; */
} else if ( p - > packet [ 9 ] = = 0x01 | | p - > packet [ 9 ] = = 0x10 ) { //second frame for MI, 3rd gen. answers in 0x10
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
if ( p - > packet [ 9 ] = = 0x01 ) {
DBGPRINTLN ( F ( " got 2nd frame (hw info) " ) ) ;
} else {
DBGPRINTLN ( F ( " 3rd gen. inverter! " ) ) ; // see table in OpenDTU code, DevInfoParser.cpp devInfo[]
}
// xlsx: HW_ECapValue is total energy?!? (data coll. inst. #154)
DPRINT ( DBG_INFO , F ( " HW_PartNo " ) ) ;
DBGPRINTLN ( String ( ( uint32_t ) ( ( ( p - > packet [ 10 ] < < 8 ) | p - > packet [ 11 ] ) < < 8 | p - > packet [ 12 ] ) < < 8 | p - > packet [ 13 ] ) ) ;
//DBGPRINTLN(String((p->packet[12] << 8) + p->packet[13]));
if ( p - > packet [ 9 ] = = 0x01 ) {
iv - > setValue ( iv - > getPosByChFld ( 0 , FLD_YT , rec ) , rec , ( float ) ( ( p - > packet [ 20 ] < < 8 ) + p - > packet [ 21 ] ) / 1 ) ;
if ( mSerialDebug ) {
DPRINT ( DBG_INFO , F ( " HW_ECapValue " ) ) ;
DBGPRINTLN ( String ( ( p - > packet [ 20 ] < < 8 ) + p - > packet [ 21 ] ) ) ;
DPRINT ( DBG_INFO , F ( " HW_FB_TLmValue " ) ) ;
DBGPRINTLN ( String ( ( p - > packet [ 14 ] < < 8 ) + p - > packet [ 15 ] ) ) ;
DPRINT ( DBG_INFO , F ( " HW_FB_ReSPRT " ) ) ;
DBGPRINTLN ( String ( ( p - > packet [ 16 ] < < 8 ) + p - > packet [ 17 ] ) ) ;
DPRINT ( DBG_INFO , F ( " HW_GridSamp_ResValule " ) ) ;
DBGPRINTLN ( String ( ( p - > packet [ 18 ] < < 8 ) + p - > packet [ 19 ] ) ) ;
}
}
} else if ( p - > packet [ 9 ] = = 0x12 ) { //3rd frame
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINTLN ( F ( " got 3rd frame (hw info) " ) ) ;
iv - > setQueuedCmdFinished ( ) ;
mStat - > rxSuccess + + ;
mSys - > Radio . sendCmdPacket ( iv - > radioId . u64 , 0x0f , 0x01 , false ) ;
} else if ( p - > packet [ 9 ] = = 0x01 ) { //second frame
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) got 2nd frame (hw info) " ) ) ;
mSys - > Radio . sendCmdPacket ( iv - > radioId . u64 , 0x0f , 0x12 , false ) ;
} else if ( p - > packet [ 9 ] = = 0x12 ) { //3rd frame
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) got 3rd frame (hw info) " ) ) ;
}
} else if ( p - > packet [ 0 ] = = ( TX_REQ_INFO + ALL_FRAMES ) ) { // response from get information command
// atm, we just do nothing else than print out what we got...
// for decoding see xls- Data collection instructions - #147ff
mPayload [ iv - > id ] . txId = p - > packet [ 0 ] ;
} else if ( p - > packet [ 0 ] = = ( TX_REQ_INFO + ALL_FRAMES ) // response from get information command
| | ( p - > packet [ 0 ] = = 0xB6 & & mPayload [ iv - > id ] . txCmd ! = 0x36 ) ) { // strange short response from MI-1500 3rd gen; might be missleading!
// atm, we just do nothing else than print out what we got...
// for decoding see xls- Data collection instructions - #147ff
//mPayload[iv->id].txId = p->packet[0];
DPRINTLN ( DBG_DEBUG , F ( " Response from info request received " ) ) ;
uint8_t * pid = & p - > packet [ 9 ] ;
if ( * pid = = 0x00 ) {
DPRINT ( DBG_DEBUG , F ( " fragment number zero received " ) ) ;
iv - > setQueuedCmdFinished ( ) ;
} //else {
DPRINTLN ( DBG_DEBUG , " PID: 0x " + String ( * pid , HEX ) ) ;
/*
if ( ( * pid & 0x7F ) < MAX_PAYLOAD_ENTRIES ) {
} else if ( p - > packet [ 9 ] = = 0x81 ) { // might need some additional check, as this is only ment for short answers!
DPRINT_IVID ( DBG_WARN , iv - > id ) ;
DBGPRINTLN ( F ( " seems to use 3rd gen. protocol - switching ivGen! " ) ) ;
iv - > ivGen = IV_HM ;
iv - > setQueuedCmdFinished ( ) ;
iv - > clearCmdQueue ( ) ;
//DPRINTLN(DBG_DEBUG, "PID: 0x" + String(*pid, HEX));
/* (old else-tree)
if ( ( * pid & 0x7F ) < MAX_PAYLOAD_ENTRIES ) { ^
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 ] . gotFragment = true ;
@ -212,30 +301,36 @@ const byteAssign_t InfoAssignment[] = {
if ( * pid > 0x81 )
mPayload [ iv - > id ] . lastFound = true ;
}
}
} */
}
} */
} else if ( p - > packet [ 0 ] = = ( TX_REQ_DEVCONTROL + ALL_FRAMES ) ) { // response from dev control command
DPRINTLN ( DBG_DEBUG , F ( " Response from devcontrol request received " ) ) ;
//}
} else if ( p - > packet [ 0 ] = = ( TX_REQ_DEVCONTROL + ALL_FRAMES ) // response from dev control command
| | p - > packet [ 0 ] = = ( TX_REQ_DEVCONTROL + ALL_FRAMES - 1 ) ) { // response from DRED instruction
DPRINT_IVID ( DBG_DEBUG , iv - > id ) ;
DBGPRINTLN ( F ( " Response from devcontrol request received " ) ) ;
mPayload [ iv - > id ] . txId = p - > packet [ 0 ] ;
iv - > clearDevControlRequest ( ) ;
if ( ( p - > packet [ 12 ] = = ActivePowerContr ) & & ( p - > packet [ 13 ] = = 0x00 ) ) {
String msg = " " ;
if ( ( p - > packet [ 10 ] = = 0x00 ) & & ( p - > packet [ 11 ] = = 0x00 ) )
mApp - > setMqttPowerLimitAck ( iv ) ;
else
msg = " NOT " ;
DPRINTLN ( DBG_INFO , F ( " Inverter " ) + String ( iv - > id ) + F ( " has " ) + msg + F ( " accepted power limit set point " ) + String ( iv - > powerLimit [ 0 ] ) + F ( " with PowerLimitControl " ) + String ( iv - > powerLimit [ 1 ] ) ) ;
if ( ( p - > packet [ 9 ] = = 0x5a ) & & ( p - > packet [ 10 ] = = 0x5a ) ) {
mApp - > setMqttPowerLimitAck ( iv ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " has accepted power limit set point " ) ) ;
DBGPRINT ( String ( iv - > powerLimit [ 0 ] ) ) ;
DBGPRINT ( F ( " with PowerLimitControl " ) ) ;
DBGPRINTLN ( String ( iv - > powerLimit [ 1 ] ) ) ;
iv - > clearCmdQueue ( ) ;
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));
DPRINT ( DBG_INFO , F ( " procPyld: cmd: 0x " ) ) ;
DBGHEXLN ( mPayload [ iv - > id ] . txCmd ) ;
DPRINT ( DBG_INFO , F ( " procPyld: txid: 0x " ) ) ;
DBGHEXLN ( mPayload [ iv - > id ] . txId ) ;
//DPRINT(DBG_DEBUG, F("procPyld: max: "));
//DBGPRINTLN(String(mPayload[iv->id].maxPackId));
record_t < > * rec = iv - > getRecordStruct ( mPayload [ iv - > id ] . txCmd ) ; // choose the parser
mPayload [ iv - > id ] . complete = true ;
@ -317,10 +412,10 @@ const byteAssign_t InfoAssignment[] = {
//delayed next message?
//mPayload[iv->id].skipfirstrepeat++;
if ( mPayload [ iv - > id ] . skipfirstrepeat ) {
mPayload [ iv - > id ] . skipfirstrepeat = 0 ; //reset counter*/
/*if (mPayload[iv->id].skipfirstrepeat) {
mPayload [ iv - > id ] . skipfirstrepeat = 0 ; //reset counter
continue ; // skip to next inverter
}
} */
if ( ! mPayload [ iv - > id ] . complete ) {
//DPRINTLN(DBG_INFO, F("Pyld incompl code")); //info for testing only
@ -330,21 +425,20 @@ const byteAssign_t InfoAssignment[] = {
if ( ( mPayload [ iv - > id ] . requested ) & & ( retransmit ) ) {
if ( iv - > devControlCmd = = Restart | | iv - > devControlCmd = = CleanState_LockAndAlarm ) {
// This is required to prevent retransmissions without answer.
DPRINTLN ( DBG_INFO , F ( " Prevent retransmit on Restart / CleanState_LockAndAlarm... " ) ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINTLN ( F ( " Prevent retransmit on Restart / CleanState_LockAndAlarm... " ) ) ;
mPayload [ iv - > id ] . retransmits = mMaxRetrans ;
} else if ( iv - > devControlCmd = = ActivePowerContr ) {
DPRINT ( DBG_INFO , F ( " (# " ) ) ;
DBGPRINT ( String ( iv - > id ) ) ;
DBGPRINTLN ( F ( " ) retransmit power limit " ) ) ;
mSys - > Radio . sendControlPacket ( iv - > radioId . u64 , iv - > devControlCmd , iv - > powerLimit , true ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINTLN ( F ( " retransmit power limit " ) ) ;
mSys - > Radio . sendControlPacket ( iv - > radioId . u64 , iv - > devControlCmd , iv - > powerLimit , true , false ) ;
} else {
uint8_t cmd = mPayload [ iv - > id ] . txCmd ;
if ( mPayload [ iv - > id ] . retransmits < mMaxRetrans ) {
mPayload [ iv - > id ] . retransmits + + ;
if ( ! mPayload [ iv - > id ] . gotFragment ) {
DPRINT ( DBG_INFO , F ( " (# " ) ) ;
DBGPRINT ( String ( iv - > id ) ) ;
DBGPRINTLN ( F ( " ) nothing received " ) ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINTLN ( F ( " nothing received " ) ) ;
mPayload [ iv - > id ] . retransmits = mMaxRetrans ;
} else if ( cmd = = 0x0f ) {
//hard/firmware request
@ -358,28 +452,32 @@ const byteAssign_t InfoAssignment[] = {
change = true ;
} else if ( cmd = = 0x09 ) { //MI single or dual channel device
if ( mPayload [ iv - > id ] . dataAB [ CH1 ] & & iv - > type = = INV_TYPE_2CH ) {
if ( ! mPayload [ iv - > id ] . stsAB [ CH2 ] | | ! mPayload [ iv - > id ] . dataAB [ CH2 ] ) {
if ( ! mPayload [ iv - > id ] . stsAB [ CH1 ] & & mPayload [ iv - > id ] . retransmits < 2 ) { }
//first try to get missing sts for first channel a second time
else if ( ! mPayload [ iv - > id ] . stsAB [ CH2 ] | | ! mPayload [ iv - > id ] . dataAB [ CH2 ] ) {
cmd = 0x11 ;
change = true ;
mPayload [ iv - > id ] . retransmits = 0 ; //reset counter
}
}
} 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 ] ) {
if ( mPayload [ iv - > id ] . dataAB [ CH2 ] ) { // data + status ch2 are there?
if ( mPayload [ iv - > id ] . stsAB [ CH2 ] & & ( ! mPayload [ iv - > id ] . stsAB [ CH1 ] | | ! mPayload [ iv - > id ] . dataAB [ CH1 ] ) ) {
cmd = 0x09 ;
change = true ;
}
}
}
DPRINT ( DBG_INFO , F ( " (# " ) ) ;
DBGPRINT ( String ( iv - > id ) ) ;
DBGPRINT ( F ( " ) " ) ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
if ( change ) {
DBGPRINT ( F ( " next request is 0x " ) ) ;
DBGPRINT ( F ( " next request is " ) ) ;
//mPayload[iv->id].skipfirstrepeat = 0;
} else {
DBGPRINT ( F ( " not complete: Request Retransmit 0x " ) ) ;
DBGPRINT ( F ( " sth. " ) ) ;
DBGPRINT ( F ( " missing: Request Retransmit " ) ) ;
}
DBGPRINTLN ( String ( cmd , HEX ) ) ;
DBGPRINT ( F ( " 0x " ) ) ;
DBGHEXLN ( cmd ) ;
//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 ;
@ -391,9 +489,13 @@ const byteAssign_t InfoAssignment[] = {
} else if ( ! crcPass & & pyldComplete ) { // crc error on complete Payload
if ( mPayload [ iv - > id ] . retransmits < mMaxRetrans ) {
mPayload [ iv - > id ] . retransmits + + ;
DPRINTLN ( DBG_WARN , F ( " CRC Error: Request Complete Retransmit " ) ) ;
DPRINT_IVID ( DBG_WARN , iv - > id ) ;
DBGPRINTLN ( F ( " CRC Error: Request Complete Retransmit " ) ) ;
mPayload [ iv - > id ] . txCmd = iv - > getQueuedCmd ( ) ;
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) prepareDevInformCmd 0x " ) + String ( mPayload [ iv - > id ] . txCmd , HEX ) ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " prepareDevInformCmd 0x " ) ) ;
DBGHEXLN ( mPayload [ iv - > id ] . txCmd ) ;
mSys - > Radio . prepareDevInformCmd ( iv - > radioId . u64 , mPayload [ iv - > id ] . txCmd , mPayload [ iv - > id ] . ts , iv - > alarmMesIndex , true ) ;
}
}
@ -403,16 +505,6 @@ const byteAssign_t InfoAssignment[] = {
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 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 ) ) ;
DPRINTLN ( DBG_INFO , F ( " process: 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;
//memset(payload, 0, 128);
@ -468,48 +560,76 @@ const byteAssign_t InfoAssignment[] = {
( mCbMiPayload ) ( val ) ;
}
void miStsDecode ( Inverter < > * iv , packet_t * p , uint8_t chan = CH1 ) {
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) status msg 0x " ) + String ( p - > packet [ 0 ] , HEX ) ) ;
void miStsDecode ( Inverter < > * iv , packet_t * p , uint8_t sts chan = CH1 ) {
//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
rec - > ts = mPayload [ iv - > id ] . ts ;
mPayload [ iv - > id ] . gotFragment = true ;
mPayload [ iv - > id ] . txId = p - > packet [ 0 ] ;
uint8_t status = ( p - > packet [ 11 ] < < 8 ) + p - > packet [ 12 ] ;
uint8_t stschan = p - > packet [ 0 ] = = 0x88 ? CH1 : CH2 ;
mPayload [ iv - > id ] . sts [ stschan ] = status ;
miStsConsolidate ( iv , stschan , rec , p - > packet [ 10 ] , p - > packet [ 12 ] , p - > packet [ 9 ] , p - > packet [ 11 ] ) ;
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 ) ;
//mPayload[iv->id].skipfirstrepeat = 1;
if ( mPayload [ iv - > id ] . stsAB [ CH0 ] & & mPayload [ iv - > id ] . dataAB [ CH0 ] & & ! mPayload [ iv - > id ] . complete ) {
miComplete ( iv ) ;
}
}
void miStsConsolidate ( Inverter < > * iv , uint8_t stschan , record_t < > * rec , uint8_t uState , uint8_t uEnum , uint8_t lState = 0 , uint8_t lEnum = 0 ) {
//uint8_t status = (p->packet[11] << 8) + p->packet[12];
uint16_t status = 3 ; // regular status for MI, change to 1 later?
if ( uState = = 2 ) {
status = 5050 + stschan ; //first approach, needs review!
if ( lState )
status + = lState * 10 ;
} else if ( uState > 3 ) {
status = uState * 1000 + uEnum * 10 ;
if ( lState )
status + = lState * 100 ; //needs review, esp. for 4ch-8310 state!
//if (lEnum)
status + = lEnum ;
if ( uEnum < 6 ) {
status + = stschan ;
}
if ( status = = 8000 )
status = 8310 ; //trick?
}
uint16_t prntsts = status = = 3 ? 1 : status ;
if ( status ! = mPayload [ iv - > id ] . sts [ stschan ] ) { //sth.'s changed?
mPayload [ iv - > id ] . sts [ stschan ] = status ;
DPRINT ( DBG_WARN , F ( " Status change for CH " ) ) ;
DBGPRINT ( String ( stschan ) ) ; DBGPRINT ( F ( " ( " ) ) ;
DBGPRINT ( String ( prntsts ) ) ; DBGPRINT ( F ( " ): " ) ) ;
DBGPRINTLN ( iv - > getAlarmStr ( prntsts ) ) ;
}
if ( ! mPayload [ iv - > id ] . sts [ 0 ] | | prntsts < mPayload [ iv - > id ] . sts [ 0 ] ) {
mPayload [ iv - > id ] . sts [ 0 ] = prntsts ;
iv - > setValue ( iv - > getPosByChFld ( 0 , FLD_EVT , rec ) , rec , prntsts ) ;
}
if ( iv - > alarmMesIndex < rec - > record [ iv - > getPosByChFld ( 0 , FLD_EVT , rec ) ] ) {
iv - > alarmMesIndex = rec - > record [ iv - > getPosByChFld ( 0 , FLD_EVT , rec ) ] ; // seems there's no status per channel in 3rd gen. models?!?
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) alarm ID incremented to " ) + String ( iv - > alarmMesIndex ) ) ;
iv - > enqueCommand < InfoCommand > ( AlarmData ) ;
}
//mPayload[iv->id].skipfirstrepeat = 1;
if ( mPayload [ iv - > id ] . stsAB [ CH0 ] & & mPayload [ iv - > id ] . dataAB [ CH0 ] & & ! mPayload [ iv - > id ] . complete ) {
miComplete ( iv ) ;
/*mPayload[iv->id].complete = true;
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) got all msgs " ) ) ;
iv - > setValue ( iv - > getPosByChFld ( 0 , FLD_YD , rec ) , rec , calcYieldDayCh0 ( iv , 0 ) ) ;
//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 ) ) ;
iv - > setQueuedCmdFinished ( ) ;
iv - > doCalculations ( ) ;
mPayload [ iv - > id ] . skipfirstrepeat = 0 ;
notify ( mPayload [ iv - > id ] . txCmd ) ;
yield ( ) ; */
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT ( F ( " alarm ID incremented to " ) ) ;
DBGPRINTLN ( String ( iv - > alarmMesIndex ) ) ;
}
/*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 ! = mCbAlarm )
( mCbAlarm ) ( code , start , end ) ;
yield ( ) ;
}
} */
}
void miDataDecode ( Inverter < > * iv , packet_t * p ) {
@ -521,7 +641,7 @@ const byteAssign_t InfoAssignment[] = {
( p - > packet [ 0 ] = = 0x91 | | p - > packet [ 0 ] = = ( 0x37 + ALL_FRAMES ) ) ? CH2 :
p - > packet [ 0 ] = = ( 0x38 + ALL_FRAMES ) ? CH3 :
CH4 ;
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) data msg 0x " ) + String ( p - > packet [ 0 ] , HEX ) + F ( " channel " ) + datachan ) ;
//DPRINTLN(DBG_INFO, F("(#") + String(iv->id) + F(") data msg 0x") + String(p->packet[0], HEX) + F(" channel ") + datachan);
// count in RF_communication_protocol.xlsx is with offset = -1
iv - > setValue ( iv - > getPosByChFld ( datachan , FLD_UDC , rec ) , rec , ( float ) ( ( p - > packet [ 9 ] < < 8 ) + p - > packet [ 10 ] ) / 10 ) ;
yield ( ) ;
@ -554,12 +674,14 @@ const byteAssign_t InfoAssignment[] = {
FCODE = ( uint8_t ) ( p - > packet [ 27 ] ) ;
} */
uint8_t status = ( uint8_t ) ( p - > packet [ 23 ] ) ;
/*uint16_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 ) ;
}
} */
miStsConsolidate ( iv , datachan , rec , p - > packet [ 23 ] , p - > packet [ 24 ] ) ;
if ( p - > packet [ 0 ] < ( 0x39 + ALL_FRAMES ) ) {
/*uint8_t cmd = p->packet[0] - ALL_FRAMES + 1;
@ -575,37 +697,21 @@ const byteAssign_t InfoAssignment[] = {
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 ) ] ;
DPRINTLN ( DBG_INFO , F ( " alarm ID incremented to " ) + String ( iv - > alarmMesIndex ) ) ;
//iv->enqueCommand<InfoCommand>(AlarmData);
}
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINT_TXT ( TXT_INCRALM ) ;
DBGPRINTLN ( String ( iv - > alarmMesIndex ) ) ;
} */
}
if ( mPayload [ iv - > id ] . complete | | //4ch device
if ( mPayload [ iv - > id ] . complete | | //4ch device
( iv - > type ! = INV_TYPE_4CH //other devices
& & mPayload [ iv - > id ] . dataAB [ CH0 ]
& & mPayload [ iv - > id ] . stsAB [ CH0 ] ) ) {
miComplete ( iv ) ;
/*mPayload[iv->id].complete = true; // For 2 CH devices, this might be too short...
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) got all msgs " ) ) ;
iv - > setValue ( iv - > getPosByChFld ( 0 , FLD_YD , rec ) , rec , calcYieldDayCh0 ( iv , 0 ) ) ;
//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 ) ) ;
iv - > doCalculations ( ) ;
iv - > setQueuedCmdFinished ( ) ;
mStat - > rxSuccess + + ;
yield ( ) ;
notify ( mPayload [ iv - > id ] . txCmd ) ; */
}
@ -627,16 +733,25 @@ const byteAssign_t InfoAssignment[] = {
}
void miComplete ( Inverter < > * iv ) {
if ( mPayload [ iv - > id ] . complete )
return ; //if we got second message as well in repreated attempt
mPayload [ iv - > id ] . complete = true ; // For 2 CH devices, this might be too short...
DPRINTLN ( DBG_INFO , F ( " (# " ) + String ( iv - > id ) + F ( " ) got all msgs " ) ) ;
DPRINT_IVID ( DBG_INFO , iv - > id ) ;
DBGPRINTLN ( F ( " got all msgs " ) ) ;
record_t < > * rec = iv - > getRecordStruct ( RealTimeRunData_Debug ) ;
iv - > setValue ( iv - > getPosByChFld ( 0 , FLD_YD , rec ) , rec , calcYieldDayCh0 ( iv , 0 ) ) ;
//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 ) ) ;
float ac_pow = 0 ;
for ( uint8_t i = 1 ; i < = iv - > channels ; i + + ) {
if ( mPayload [ iv - > id ] . sts [ i ] = = 3 ) {
uint8_t pos = iv - > getPosByChFld ( i , FLD_PDC , rec ) ;
ac_pow + = iv - > getValue ( pos , rec ) ;
}
}
ac_pow = ( int ) ( ac_pow * 9.5 ) ;
iv - > setValue ( iv - > getPosByChFld ( 0 , FLD_PAC , rec ) , rec , ( float ) ac_pow / 10 ) ;
iv - > doCalculations ( ) ;
iv - > setQueuedCmdFinished ( ) ;
mStat - > rxSuccess + + ;
@ -646,37 +761,24 @@ const byteAssign_t InfoAssignment[] = {
bool build ( uint8_t id , bool * complete ) {
DPRINTLN ( DBG_VERBOSE , F ( " build " ) ) ;
/*uint16_t crc = 0xffff, crcRcv = 0x0000;
if ( mPayload [ id ] . maxPackId > MAX_PAYLOAD_ENTRIES )
mPayload [ id ] . maxPackId = MAX_PAYLOAD_ENTRIES ;
*/
// check if all messages are there
* complete = mPayload [ id ] . complete ;
uint8_t txCmd = mPayload [ id ] . txCmd ;
//uint8_t cmd = getQueuedCmd();
if ( ! * complete ) {
DPRINTLN ( DBG_VERBOSE , F ( " incomlete, txCmd is 0x " ) + String ( txCmd , HEX ) ) ; // + F("cmd is 0x") + String(cmd, HEX));
DPRINTLN ( DBG_VERBOSE , F ( " incomlete, txCmd is 0x " ) + String ( txCmd , HEX ) ) ;
//DBGHEXLN(txCmd);
if ( txCmd = = 0x09 | | txCmd = = 0x11 | | ( txCmd > = 0x36 & & txCmd < = 0x39 ) )
return false ;
}
/*for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) {
if ( mPayload [ id ] . len [ i ] > 0 ) {
if ( i = = ( mPayload [ id ] . maxPackId - 1 ) ) {
crc = ah : : crc16 ( mPayload [ id ] . data [ i ] , mPayload [ id ] . len [ i ] - 2 , crc ) ;
crcRcv = ( mPayload [ id ] . data [ i ] [ mPayload [ id ] . len [ i ] - 2 ] < < 8 ) | ( mPayload [ id ] . data [ i ] [ mPayload [ id ] . len [ i ] - 1 ] ) ;
} else
crc = ah : : crc16 ( mPayload [ id ] . data [ i ] , mPayload [ id ] . len [ i ] , crc ) ;
}
yield ( ) ;
}
return ( crc = = crcRcv ) ? true : false ; */
return true ;
}
void reset ( uint8_t id ) {
DPRINTLN ( DBG_INFO , F ( " resetPayload: id: " ) + String ( id ) ) ;
void reset ( uint8_t id , bool clrSts = false ) {
DPRINT_IVID ( DBG_INFO , id ) ;
DBGPRINTLN ( F ( " resetPayload " ) ) ;
memset ( mPayload [ id ] . len , 0 , MAX_PAYLOAD_ENTRIES ) ;
mPayload [ id ] . gotFragment = false ;
/*mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES;
@ -690,14 +792,17 @@ const byteAssign_t InfoAssignment[] = {
mPayload [ id ] . stsAB [ CH1 ] = true ; //required for 1CH and 2CH devices
mPayload [ id ] . stsAB [ CH2 ] = true ; //only required for 2CH devices
mPayload [ id ] . txCmd = 0 ;
mPayload [ id ] . skipfirstrepeat = 0 ;
//mPayload[id].skipfirstrepeat = 0;
mPayload [ id ] . requested = false ;
mPayload [ id ] . ts = * mTimestamp ;
mPayload [ id ] . sts [ 0 ] = 0 ; //disable this in case gotFragment is not working
mPayload [ id ] . sts [ CH1 ] = 0 ;
mPayload [ id ] . sts [ CH2 ] = 0 ;
mPayload [ id ] . sts [ CH3 ] = 0 ;
mPayload [ id ] . sts [ CH4 ] = 0 ;
mPayload [ id ] . sts [ 0 ] = 0 ;
if ( clrSts ) { // only clear channel states at startup
mPayload [ id ] . sts [ CH1 ] = 0 ;
mPayload [ id ] . sts [ CH2 ] = 0 ;
mPayload [ id ] . sts [ CH3 ] = 0 ;
mPayload [ id ] . sts [ CH4 ] = 0 ;
mPayload [ id ] . sts [ 5 ] = 0 ; //remember last summarized state
}
}