Browse Source

Merge branch 'rejoe2-development03' into development03

pull/1163/head
lumapu 1 year ago
parent
commit
c17c078a62
  1. 69
      src/hm/hmPayload.h
  2. 442
      src/hm/miPayload.h

69
src/hm/hmPayload.h

@ -232,8 +232,9 @@ class HmPayload {
} }
if (!mPayload[iv->id].complete) { if (!mPayload[iv->id].complete) {
bool crcPass, pyldComplete; bool crcPass, pyldComplete, fastNext;
crcPass = build(iv->id, &pyldComplete);
crcPass = build(iv, &pyldComplete, &fastNext);
if (!crcPass && !pyldComplete) { // payload not complete if (!crcPass && !pyldComplete) { // payload not complete
if ((mPayload[iv->id].requested) && (retransmit)) { if ((mPayload[iv->id].requested) && (retransmit)) {
if (mPayload[iv->id].retransmits < mMaxRetrans) { if (mPayload[iv->id].retransmits < mMaxRetrans) {
@ -260,10 +261,12 @@ class HmPayload {
} else { } else {
for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) { for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId - 1); i++) {
if (mPayload[iv->id].len[i] == 0) { if (mPayload[iv->id].len[i] == 0) {
if (mSerialDebug) {
DPRINT_IVID(DBG_WARN, iv->id); DPRINT_IVID(DBG_WARN, iv->id);
DBGPRINT(F("Frame ")); DBGPRINT(F("Frame "));
DBGPRINT(String(i + 1)); DBGPRINT(String(i + 1));
DBGPRINTLN(F(" missing: Request Retransmit")); DBGPRINTLN(F(" missing: Request Retransmit"));
}
mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true); mRadio->sendCmdPacket(iv->radioId.u64, TX_REQ_INFO, (SINGLE_FRAME + i), true);
break; // only request retransmit one frame per loop break; // only request retransmit one frame per loop
} }
@ -276,20 +279,25 @@ class HmPayload {
} else if(!crcPass && pyldComplete) { // crc error on complete Payload } else if(!crcPass && pyldComplete) { // crc error on complete Payload
if (mPayload[iv->id].retransmits < mMaxRetrans) { if (mPayload[iv->id].retransmits < mMaxRetrans) {
mPayload[iv->id].retransmits++; mPayload[iv->id].retransmits++;
DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit"));
mPayload[iv->id].txCmd = iv->getQueuedCmd(); mPayload[iv->id].txCmd = iv->getQueuedCmd();
if (mSerialDebug) {
DPRINTLN(DBG_WARN, F("CRC Error: Request Complete Retransmit"));
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(mPayload[iv->id].txCmd); DBGHEXLN(mPayload[iv->id].txCmd);
}
mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true); mRadio->prepareDevInformCmd(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].ts, iv->alarmMesIndex, true);
} }
} else { // payload complete } else { // payload complete
DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); if (mSerialDebug) {
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("procPyld: cmd: 0x"));
DBGHEXLN(mPayload[iv->id].txCmd); DBGHEXLN(mPayload[iv->id].txCmd);
//DPRINT(DBG_DEBUG, F("procPyld: txid: 0x")); //DPRINT(DBG_DEBUG, F("procPyld: txid: 0x"));
//DBGHEXLN(mPayload[iv->id].txId); //DBGHEXLN(mPayload[iv->id].txId);
DPRINT(DBG_DEBUG, F("procPyld: max: ")); DPRINT(DBG_DEBUG, F("procPyld: max: "));
DPRINTLN(DBG_DEBUG, String(mPayload[iv->id].maxPackId)); DPRINTLN(DBG_DEBUG, 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;
@ -347,13 +355,25 @@ class HmPayload {
yield(); yield();
} }
} }
if( (InverterDevInform_All == mPayload[iv->id].txCmd) && (mHighPrioIv == NULL) ) // process next request immediately if possible if (fastNext) {
mHighPrioIv = iv; uint8_t cmd = iv->getQueuedCmd();
if (mSerialDebug) {
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("fast mode "));
DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd);
}
mStat->rxSuccess++;
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
mPayload[iv->id].txCmd = cmd;
}
} else { } else {
if (mSerialDebug) {
DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); DPRINT(DBG_ERROR, F("plausibility check failed, expected "));
DBGPRINT(String(rec->pyldLen)); DBGPRINT(String(rec->pyldLen));
DBGPRINTLN(F(" bytes")); DBGPRINTLN(F(" bytes"));
}
mStat->rxFail++; mStat->rxFail++;
} }
@ -370,33 +390,46 @@ class HmPayload {
(mCbPayload)(val, iv); (mCbPayload)(val, iv);
} }
bool build(uint8_t id, bool *complete) { bool build(Inverter<> *iv, bool *complete, bool *fastNext ) {
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[iv->id].maxPackId > MAX_PAYLOAD_ENTRIES)
mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; mPayload[iv->id].maxPackId = MAX_PAYLOAD_ENTRIES;
// check if all fragments are there // check if all fragments are there
*complete = true; *complete = true;
for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { *fastNext = false;
if(mPayload[id].len[i] == 0) for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) {
if(mPayload[iv->id].len[i] == 0) {
*complete = false; *complete = false;
} }
}
if(!*complete) if(!*complete)
return false; return false;
for (uint8_t i = 0; i < mPayload[id].maxPackId; i++) { for (uint8_t i = 0; i < mPayload[iv->id].maxPackId; i++) {
if (mPayload[id].len[i] > 0) { if (mPayload[iv->id].len[i] > 0) {
if (i == (mPayload[id].maxPackId - 1)) { if (i == (mPayload[iv->id].maxPackId - 1)) {
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i] - 2, crc); crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->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]); crcRcv = (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 2] << 8) | (mPayload[iv->id].data[i][mPayload[iv->id].len[i] - 1]);
} else } else
crc = ah::crc16(mPayload[id].data[i], mPayload[id].len[i], crc); crc = ah::crc16(mPayload[iv->id].data[i], mPayload[iv->id].len[i], crc);
} }
yield(); yield();
} }
return (crc == crcRcv) ? true : false; //return (crc == crcRcv) ? true : false;
if (crc != crcRcv)
return false;
//requests to cause the next request to be executed immediately
if ( mPayload[iv->id].txCmd < 11 || mPayload[iv->id].txCmd > 18 ) {
*fastNext = true;
//DPRINT_IVID(DBG_INFO, iv->id);
//DBGPRINTLN(F("fast next req"));
}
return true;
} }
void reset(uint8_t id) { void reset(uint8_t id) {

442
src/hm/miPayload.h

@ -26,10 +26,8 @@ typedef struct {
uint8_t invId; uint8_t invId;
uint8_t retransmits; uint8_t retransmits;
bool gotFragment; bool gotFragment;
/* uint8_t rtrRes; // for limiting resets
uint8_t data[MAX_PAYLOAD_ENTRIES][MAX_RF_PAYLOAD_SIZE]; uint8_t multi_parts; // for quality
uint8_t maxPackId;
bool lastFound;*/
} miPayload_t; } miPayload_t;
@ -102,6 +100,7 @@ class MiPayload {
DBGPRINTLN(F(")")); DBGPRINTLN(F(")"));
} }
} }
mPayload[iv->id].complete = true;
iv->setQueuedCmdFinished(); // command failed iv->setQueuedCmdFinished(); // command failed
} }
} }
@ -131,12 +130,9 @@ class MiPayload {
mPayload[iv->id].limitrequested = true; mPayload[iv->id].limitrequested = true;
iv->clearCmdQueue(); iv->clearCmdQueue();
iv->enqueCommand<InfoCommand>(SystemConfigPara); // try to read back power limit //iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit is not possible with MI
} else { } else {
uint8_t cmd = iv->getQueuedCmd(); uint8_t cmd = iv->getQueuedCmd();
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd);
uint8_t cmd2 = cmd; uint8_t cmd2 = cmd;
if ( cmd == SystemConfigPara ) { //0x05 for HM-types if ( cmd == SystemConfigPara ) { //0x05 for HM-types
if (!mPayload[iv->id].limitrequested) { // only do once at startup if (!mPayload[iv->id].limitrequested) { // only do once at startup
@ -148,12 +144,15 @@ class MiPayload {
} }
if (cmd == 0x01 || cmd == SystemConfigPara ) { //0x1 and 0x05 for HM-types 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? cmd2 = cmd == SystemConfigPara ? 0x01 : 0x00; //perhaps we can only try to get second frame?
cmd = 0x0f; // for MI, these seem to make part of polling the device software and hardware version number command
}
if (mSerialDebug) {
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd);
}
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, false); mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, false);
} else {
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd2, false, false);
};
mPayload[iv->id].txCmd = cmd; mPayload[iv->id].txCmd = cmd;
if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) { if (iv->type == INV_TYPE_1CH || iv->type == INV_TYPE_2CH) {
@ -161,14 +160,13 @@ class MiPayload {
mPayload[iv->id].stsAB[CH1] = false; mPayload[iv->id].stsAB[CH1] = false;
mPayload[iv->id].dataAB[CH0] = false; mPayload[iv->id].dataAB[CH0] = false;
mPayload[iv->id].stsAB[CH0] = false; mPayload[iv->id].stsAB[CH0] = false;
}
if (iv->type == INV_TYPE_2CH) { if (iv->type == INV_TYPE_2CH) {
mPayload[iv->id].dataAB[CH2] = false; mPayload[iv->id].dataAB[CH2] = false;
mPayload[iv->id].stsAB[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));
@ -190,125 +188,8 @@ class MiPayload {
else if (p->packet[0] == ( 0x0f + ALL_FRAMES)) { else if (p->packet[0] == ( 0x0f + ALL_FRAMES)) {
// MI response from get hardware information request // MI response from get hardware information request
record_t<> *rec = iv->getRecordStruct(InverterDevInform_All); // choose the record structure miHwDecode(iv, p);
rec->ts = mPayload[iv->id].ts; mPayload[iv->id].txId = p->packet[0];
mPayload[iv->id].gotFragment = true;
if(mHighPrioIv == NULL) // process next request immediately if possible
mHighPrioIv = iv;
/*
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
*/
/*
case InverterDevInform_All:
rec->length = (uint8_t)(HMINFO_LIST_LEN);
rec->assign = (byteAssign_t *)InfoAssignment;
rec->pyldLen = HMINFO_PAYLOAD_LEN;
break;
const byteAssign_t InfoAssignment[] = {
{ FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 },
{ FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 },
{ FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 },
{ FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE, CH0, 6, 2, 1 },
{ FLD_BOOTLOADER_VER, UNIT_NONE, CH0, 8, 2, 1 }
};
*/
if ( p->packet[9] == 0x00 ) {//first frame
//FLD_FW_VERSION
for (uint8_t i = 0; i < 5; i++) {
iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1);
}
iv->isConnected = true;
mPayload[iv->id].gotFragment = 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]));
}
record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
rec->ts = mPayload[iv->id].ts;
iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])/1);
//notify(InverterDevInform_All, iv);
//28737
} 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)"));
/* according to xlsx (different start byte -1!)
byte[11] to byte[14] HW_PN
byte[15] byte[16] HW_FB_TLmValue
byte[17] byte[18] HW_FB_ReSPRT
byte[19] byte[20] HW_GridSamp_ResValule
byte[21] byte[22] HW_ECapValue
byte[23] to byte[26] Matching_APPFW_PN
*/
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]));
mPayload[iv->id].gotFragment = true;
record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
rec->ts = mPayload[iv->id].ts;
iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1);
if(mSerialDebug) {
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]));
DPRINT(DBG_INFO,F("HW_ECapValue "));
DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21]));
DPRINT(DBG_INFO,F("Matching_APPFW_PN "));
DBGPRINTLN(String((uint32_t) (((p->packet[22] << 8) | p->packet[23]) << 8 | p->packet[24]) << 8 | p->packet[25]));
}
//notify(InverterDevInform_Simple, iv);
notify(InverterDevInform_All, iv);
} else {
DBGPRINTLN(F("3rd gen. inverter!")); // see table in OpenDTU code, DevInfoParser.cpp devInfo[]
}
} else if ( p->packet[9] == 0x12 ) {//3rd frame
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINTLN(F("got 3rd frame (hw info)"));
/* according to xlsx (different start byte -1!)
byte[11] byte[12] APPFW_MINVER
byte[13] byte[14] HWInfoAddr
byte[15] byte[16] PNInfoCRC_gusv
byte[15] byte[16] PNInfoCRC_gusv
*/
if(mSerialDebug) {
DPRINT(DBG_INFO,F("APPFW_MINVER "));
DBGPRINTLN(String((p->packet[10] << 8) + p->packet[11]));
DPRINT(DBG_INFO,F("HWInfoAddr "));
DBGPRINTLN(String((p->packet[12] << 8) + p->packet[13]));
DPRINT(DBG_INFO,F("PNInfoCRC_gusv "));
DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15]));
DPRINT(DBG_INFO,F("PNInfoCRC_gusv (pt. 2?) "));
DBGPRINTLN(String((p->packet[16] << 8) + p->packet[17]));
}
iv->setQueuedCmdFinished();
mPayload[iv->id].complete = true;
mStat->rxSuccess++;
}
} else if ( p->packet[0] == (TX_REQ_INFO + ALL_FRAMES) // response from get information command } 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 misleading! || (p->packet[0] == 0xB6 && mPayload[iv->id].txCmd != 0x36)) { // strange short response from MI-1500 3rd gen; might be misleading!
@ -326,23 +207,7 @@ const byteAssign_t InfoAssignment[] = {
iv->ivGen = IV_HM; iv->ivGen = IV_HM;
iv->setQueuedCmdFinished(); iv->setQueuedCmdFinished();
iv->clearCmdQueue(); 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;
} }
if ((*pid & ALL_FRAMES) == ALL_FRAMES) {
// Last packet
if (((*pid & 0x7f) > mPayload[iv->id].maxPackId) || (MAX_PAYLOAD_ENTRIES == mPayload[iv->id].maxPackId)) {
mPayload[iv->id].maxPackId = (*pid & 0x7f);
if (*pid > 0x81)
mPayload[iv->id].lastFound = true;
}
}*/
}
//}
} else if (p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES ) // response from dev control command } 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 || p->packet[0] == (TX_REQ_DEVCONTROL + ALL_FRAMES -1)) { // response from DRED instruction
DPRINT_IVID(DBG_DEBUG, iv->id); DPRINT_IVID(DBG_DEBUG, iv->id);
@ -354,23 +219,27 @@ const byteAssign_t InfoAssignment[] = {
if ((p->packet[9] == 0x5a) && (p->packet[10] == 0x5a)) { if ((p->packet[9] == 0x5a) && (p->packet[10] == 0x5a)) {
mApp->setMqttPowerLimitAck(iv); mApp->setMqttPowerLimitAck(iv);
iv->powerLimitAck = true; iv->powerLimitAck = true;
if (mSerialDebug) {
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("has accepted power limit set point ")); DBGPRINT(F("has accepted power limit set point "));
DBGPRINT(String(iv->powerLimit[0])); DBGPRINT(String(iv->powerLimit[0]));
DBGPRINT(F(" with PowerLimitControl ")); DBGPRINT(F(" with PowerLimitControl "));
DBGPRINTLN(String(iv->powerLimit[1])); DBGPRINTLN(String(iv->powerLimit[1]));
}
iv->clearCmdQueue(); iv->clearCmdQueue();
iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit iv->enqueCommand<InfoCommand>(SystemConfigPara); // read back power limit
} }
iv->devControlCmd = Init; iv->devControlCmd = Init;
} else { // some other response; copied from hmPayload:process; might not be correct to do that here!!! } else { // some other response; copied from hmPayload:process; might not be correct to do that here!!!
DPRINT(DBG_INFO, F("procPyld: cmd: 0x")); if (mSerialDebug) {
DPRINT_IVID(DBG_INFO,iv->id);
DBGPRINT(F("procPyld: cmd: 0x"));
DBGHEXLN(mPayload[iv->id].txCmd); DBGHEXLN(mPayload[iv->id].txCmd);
DPRINT(DBG_INFO, F("procPyld: txid: 0x")); DPRINT_IVID(DBG_INFO,iv->id);
DBGPRINT(F("procPyld: txid: 0x"));
DBGHEXLN(mPayload[iv->id].txId); 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 record_t<> *rec = iv->getRecordStruct(mPayload[iv->id].txCmd); // choose the parser
mPayload[iv->id].complete = true; mPayload[iv->id].complete = true;
@ -379,11 +248,6 @@ const byteAssign_t InfoAssignment[] = {
memset(payload, 0, 128); memset(payload, 0, 128);
/*for (uint8_t i = 0; i < (mPayload[iv->id].maxPackId); i++) {
memcpy(&payload[payloadLen], mPayload[iv->id].data[i], (mPayload[iv->id].len[i]));
payloadLen += (mPayload[iv->id].len[i]);
yield();
}*/
payloadLen -= 2; payloadLen -= 2;
if (mSerialDebug) { if (mSerialDebug) {
@ -432,7 +296,7 @@ const byteAssign_t InfoAssignment[] = {
if (NULL == iv) if (NULL == iv)
continue; // skip to next inverter continue; // skip to next inverter
if (IV_HM == iv->ivGen) // only process MI inverters if (IV_MI != iv->ivGen) // only process MI inverters
continue; // skip to next inverter continue; // skip to next inverter
if ( !mPayload[iv->id].complete && if ( !mPayload[iv->id].complete &&
@ -443,24 +307,17 @@ const byteAssign_t InfoAssignment[] = {
(mPayload[iv->id].txId != (0x11 + ALL_FRAMES)) && (mPayload[iv->id].txId != (0x11 + ALL_FRAMES)) &&
(mPayload[iv->id].txId != (0x88)) && (mPayload[iv->id].txId != (0x88)) &&
(mPayload[iv->id].txId != (0x92)) && (mPayload[iv->id].txId != (0x92)) &&
(mPayload[iv->id].txId != 0 )) { (mPayload[iv->id].txId != 0 &&
mPayload[iv->id].txCmd != 0x0f)) {
// no processing needed if txId is not one of 0x95, 0x88, 0x89, 0x91, 0x92 or response to 0x36ff // no processing needed if txId is not one of 0x95, 0x88, 0x89, 0x91, 0x92 or response to 0x36ff
mPayload[iv->id].complete = true; mPayload[iv->id].complete = true;
continue; // skip to next inverter continue; // skip to next inverter
} }
//delayed next message?
//mPayload[iv->id].skipfirstrepeat++;
/*if (mPayload[iv->id].skipfirstrepeat) {
mPayload[iv->id].skipfirstrepeat = 0; //reset counter
continue; // skip to next inverter
}*/
if (!mPayload[iv->id].complete) { if (!mPayload[iv->id].complete) {
//DPRINTLN(DBG_INFO, F("Pyld incompl code")); //info for testing only bool gotAllMsgParts, pyldComplete, fastNext;
bool crcPass, pyldComplete; gotAllMsgParts = build(iv, &pyldComplete, &fastNext);
crcPass = build(iv->id, &pyldComplete); if (!gotAllMsgParts && !pyldComplete) { // payload not complete
if (!crcPass && !pyldComplete) { // payload not complete
if ((mPayload[iv->id].requested) && (retransmit)) { if ((mPayload[iv->id].requested) && (retransmit)) {
if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) { if (iv->devControlCmd == Restart || iv->devControlCmd == CleanState_LockAndAlarm) {
// This is required to prevent retransmissions without answer. // This is required to prevent retransmissions without answer.
@ -482,8 +339,7 @@ const byteAssign_t InfoAssignment[] = {
} else if ( cmd == 0x0f ) { } else if ( cmd == 0x0f ) {
//hard/firmware request //hard/firmware request
mRadio->sendCmdPacket(iv->radioId.u64, 0x0f, 0x00, true, false); mRadio->sendCmdPacket(iv->radioId.u64, 0x0f, 0x00, true, false);
//iv->setQueuedCmdFinished(); mPayload[id].multi_parts = 0;
//cmd = iv->getQueuedCmd();
} else { } else {
bool change = false; bool change = false;
if ( cmd >= 0x36 && cmd < 0x39 ) { // MI-1500 Data command if ( cmd >= 0x36 && cmd < 0x39 ) { // MI-1500 Data command
@ -496,6 +352,7 @@ const byteAssign_t InfoAssignment[] = {
else if (!mPayload[iv->id].stsAB[CH2] || !mPayload[iv->id].dataAB[CH2] ) { else if (!mPayload[iv->id].stsAB[CH2] || !mPayload[iv->id].dataAB[CH2] ) {
cmd = 0x11; cmd = 0x11;
change = true; change = true;
if (mPayload[iv->id].rtrRes < 3) //only get back to first channel twice
mPayload[iv->id].retransmits = 0; //reset counter mPayload[iv->id].retransmits = 0; //reset counter
} }
} }
@ -510,32 +367,48 @@ const byteAssign_t InfoAssignment[] = {
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
if (change) { if (change) {
DBGPRINT(F("next request is")); DBGPRINT(F("next request is"));
//mPayload[iv->id].skipfirstrepeat = 0;
mPayload[iv->id].txCmd = cmd; mPayload[iv->id].txCmd = cmd;
mPayload[iv->id].rtrRes++;
} else { } else {
DBGPRINT(F("sth.")); DBGPRINT(F("sth."));
DBGPRINT(F(" missing: Request Retransmit")); DBGPRINT(F(" missing: Request Retransmit"));
} }
DBGPRINT(F(" 0x")); DBGPRINT(F(" 0x"));
DBGHEXLN(cmd); DBGHEXLN(cmd);
mPayload[id].multi_parts = 0;
mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd, true, false); mRadio->sendCmdPacket(iv->radioId.u64, cmd, cmd, true, false);
yield(); yield();
} }
} }
} }
} }
} else if(!crcPass && pyldComplete) { // crc error on complete Payload } else if(!gotAllMsgParts && pyldComplete) { // crc error on complete Payload
if (mPayload[iv->id].retransmits < mMaxRetrans) { if (mPayload[iv->id].retransmits < mMaxRetrans) {
mPayload[iv->id].retransmits++; mPayload[iv->id].retransmits++;
mPayload[iv->id].txCmd = iv->getQueuedCmd();
mPayload[id].multi_parts = 0;
if (mSerialDebug) {
DPRINT_IVID(DBG_WARN, iv->id); DPRINT_IVID(DBG_WARN, iv->id);
DBGPRINTLN(F("CRC Error: Request Complete Retransmit")); DBGPRINTLN(F("CRC Error: Request Complete Retransmit"));
mPayload[iv->id].txCmd = iv->getQueuedCmd();
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("prepareDevInformCmd 0x")); DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(mPayload[iv->id].txCmd); DBGHEXLN(mPayload[iv->id].txCmd);
}
mRadio->sendCmdPacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].txCmd, false, false); mRadio->sendCmdPacket(iv->radioId.u64, mPayload[iv->id].txCmd, mPayload[iv->id].txCmd, false, false);
} }
} else {
if (fastNext) {
uint8_t cmd = iv->getQueuedCmd();
if (mSerialDebug) {
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("fast mode "));
DBGPRINT(F("prepareDevInformCmd 0x"));
DBGHEXLN(cmd);
}
mStat->rxSuccess++;
mRadio->prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false);
mPayload[iv->id].txCmd = cmd;
}
} }
} }
@ -550,19 +423,15 @@ const byteAssign_t InfoAssignment[] = {
} }
void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t stschan = CH1) { void miStsDecode(Inverter<> *iv, packet_t *p, uint8_t stschan = 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 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].gotFragment = true;
mPayload[iv->id].multi_parts += 3;
mPayload[iv->id].txId = p->packet[0]; mPayload[iv->id].txId = p->packet[0];
miStsConsolidate(iv, stschan, rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]); miStsConsolidate(iv, stschan, rec, p->packet[10], p->packet[12], p->packet[9], p->packet[11]);
mPayload[iv->id].stsAB[stschan] = true; mPayload[iv->id].stsAB[stschan] = true;
if (mPayload[iv->id].stsAB[CH1] && mPayload[iv->id].stsAB[CH2]) if (mPayload[iv->id].stsAB[CH1] && mPayload[iv->id].stsAB[CH2])
mPayload[iv->id].stsAB[CH0] = true; mPayload[iv->id].stsAB[CH0] = true;
//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) { void miStsConsolidate(Inverter<> *iv, uint8_t stschan, record_t<> *rec, uint8_t uState, uint8_t uEnum, uint8_t lState = 0, uint8_t lEnum = 0) {
@ -588,24 +457,27 @@ const byteAssign_t InfoAssignment[] = {
uint16_t prntsts = statusMi == 3 ? 1 : statusMi; uint16_t prntsts = statusMi == 3 ? 1 : statusMi;
if ( statusMi != mPayload[iv->id].sts[stschan] ) { //sth.'s changed? if ( statusMi != mPayload[iv->id].sts[stschan] ) { //sth.'s changed?
mPayload[iv->id].sts[stschan] = statusMi; mPayload[iv->id].sts[stschan] = statusMi;
DPRINT(DBG_WARN, F("Status change for CH")); if (mSerialDebug) {
DPRINT(DBG_WARN, F("New state on CH"));
DBGPRINT(String(stschan)); DBGPRINT(F(" (")); DBGPRINT(String(stschan)); DBGPRINT(F(" ("));
DBGPRINT(String(prntsts)); DBGPRINT(F("): ")); DBGPRINT(String(prntsts)); DBGPRINT(F("): "));
DBGPRINTLN(iv->getAlarmStr(prntsts)); DBGPRINTLN(iv->getAlarmStr(prntsts));
} }
}
if ( !mPayload[iv->id].sts[0] || prntsts < mPayload[iv->id].sts[0] ) { if ( !mPayload[iv->id].sts[0] || prntsts < mPayload[iv->id].sts[0] ) {
mPayload[iv->id].sts[0] = prntsts; mPayload[iv->id].sts[0] = prntsts;
iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, prntsts); iv->setValue(iv->getPosByChFld(0, FLD_EVT, rec), rec, prntsts);
} }
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?!?
if (mSerialDebug) {
DPRINT_IVID(DBG_INFO, iv->id); DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINT(F("alarm ID incremented to ")); DBGPRINT(F("alarm ID incremented to "));
DBGPRINTLN(String(iv->alarmMesIndex)); DBGPRINTLN(String(iv->alarmMesIndex));
} }
}
/*if(AlarmData == mPayload[iv->id].txCmd) { /*if(AlarmData == mPayload[iv->id].txCmd) {
uint8_t i = 0; uint8_t i = 0;
uint16_t code; uint16_t code;
@ -625,6 +497,7 @@ const byteAssign_t InfoAssignment[] = {
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; mPayload[iv->id].gotFragment = true;
mPayload[iv->id].multi_parts += 4;
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 :
@ -653,50 +526,23 @@ const byteAssign_t InfoAssignment[] = {
} }
if (p->packet[0] >= (0x36 + ALL_FRAMES) ) { if (p->packet[0] >= (0x36 + ALL_FRAMES) ) {
/*For MI1500: /*For MI1500:
if (MI1500) { if (MI1500) {
STAT = (uint8_t)(p->packet[25] ); STAT = (uint8_t)(p->packet[25] );
FCNT = (uint8_t)(p->packet[26]); FCNT = (uint8_t)(p->packet[26]);
FCODE = (uint8_t)(p->packet[27]); FCODE = (uint8_t)(p->packet[27]);
}*/ }*/
/*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]); miStsConsolidate(iv, datachan, rec, p->packet[23], p->packet[24]);
if (p->packet[0] < (0x39 + ALL_FRAMES) ) { if (p->packet[0] < (0x39 + ALL_FRAMES) ) {
mPayload[iv->id].txCmd++; mPayload[iv->id].txCmd++;
mPayload[iv->id].retransmits = 0; // reserve retransmissions for each response mPayload[iv->id].retransmits = 0; // reserve retransmissions for each response
mPayload[iv->id].complete = false; mPayload[iv->id].complete = false;
} else {
miComplete(iv);
} }
} }
/*
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)
(mCbAl { FLD_YT, UNIT_KWH, CH0, CALC_YT_CH0, 0, CMD_CALC },
}*/
//if ( mPayload[iv->id].complete || //4ch device
if ( p->packet[0] == (0x39 + ALL_FRAMES) || //4ch device - last message
(iv->type != INV_TYPE_4CH //other devices
&& mPayload[iv->id].dataAB[CH0]
&& mPayload[iv->id].stsAB[CH0])) {
miComplete(iv);
}
} }
void miComplete(Inverter<> *iv) { void miComplete(Inverter<> *iv) {
@ -729,51 +575,165 @@ const byteAssign_t InfoAssignment[] = {
notify(RealTimeRunData_Debug, iv); notify(RealTimeRunData_Debug, iv);
} }
bool build(uint8_t id, bool *complete) { bool build(Inverter<> *iv, bool *complete, bool *fastNext ) {
DPRINTLN(DBG_VERBOSE, F("build")); DPRINTLN(DBG_VERBOSE, F("build"));
// check if all messages are there // check if all messages are there
*complete = mPayload[id].complete; *complete = mPayload[iv->id].complete;
uint8_t txCmd = mPayload[id].txCmd; *fastNext = false;
uint8_t txCmd = mPayload[iv->id].txCmd;
if(!*complete) { if(!*complete) {
DPRINTLN(DBG_VERBOSE, F("incomplete, txCmd is 0x") + String(txCmd, HEX)); //we got some delayed status msgs?!?
//DBGHEXLN(txCmd); if (txCmd == 0x09 || txCmd == 0x11)
if (txCmd == 0x09 || txCmd == 0x11 || (txCmd >= 0x36 && txCmd <= 0x39)) if (mPayload[iv->id].stsAB[CH0] && mPayload[iv->id].dataAB[CH0]) {
miComplete(iv);
return true;
}
return false;
DPRINTLN(DBG_VERBOSE, F("incomlete, txCmd is 0x") + String(txCmd, HEX));
if (txCmd >= 0x36 && txCmd <= 0x39) {
return false; return false;
} }
if (txCmd == 0x0f) { //hw info request, at least hw part nr. and version have to be there...
bool gotRelevant = iv->getFwVersion()
&& iv->getChannelFieldValue(CH0, FLD_PART_NUM, iv->getRecordStruct(InverterDevInform_Simple));
if (gotRelevant)
*fastNext = true;
return gotRelevant;
}
}
//check if we want the next request to be executed faster
if (txCmd == 0x0f)
*fastNext = true;
return true; return true;
} }
/* uint16_t mParseAlarmLog(uint8_t id, uint8_t pyld[], uint8_t len, uint32_t *start, uint32_t *endTime) { void miHwDecode(Inverter<> *iv, packet_t *p ) {
uint8_t startOff = 2 + id * ALARM_LOG_ENTRY_SIZE; record_t<> *rec = iv->getRecordStruct(InverterDevInform_All); // choose the record structure
if((startOff + ALARM_LOG_ENTRY_SIZE) > len) rec->ts = mPayload[iv->id].ts;
return 0; mPayload[iv->id].gotFragment = true;
uint16_t wCode = ((uint16_t)pyld[startOff]) << 8 | pyld[startOff+1]; /*
uint32_t startTimeOffset = 0, endTimeOffset = 0; 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 (((wCode >> 13) & 0x01) == 1) // check if is AM or PM /*
startTimeOffset = 12 * 60 * 60; case InverterDevInform_All:
if (((wCode >> 12) & 0x01) == 1) // check if is AM or PM rec->length = (uint8_t)(HMINFO_LIST_LEN);
endTimeOffset = 12 * 60 * 60; rec->assign = (byteAssign_t *)InfoAssignment;
rec->pyldLen = HMINFO_PAYLOAD_LEN;
break;
*start = (((uint16_t)pyld[startOff + 4] << 8) | ((uint16_t)pyld[startOff + 5])) + startTimeOffset; const byteAssign_t InfoAssignment[] = {
*endTime = (((uint16_t)pyld[startOff + 6] << 8) | ((uint16_t)pyld[startOff + 7])) + endTimeOffset; { FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 },
{ FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 },
{ FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 },
{ FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE, CH0, 6, 2, 1 },
{ FLD_BOOTLOADER_VER, UNIT_NONE, CH0, 8, 2, 1 }
};
*/
DPRINTLN(DBG_INFO, "Alarm #" + String(pyld[startOff+1]) + " '" + String(getAlarmStr(pyld[startOff+1])) + "' start: " + ah::getTimeStr(*start) + ", end: " + ah::getTimeStr(*endTime)); if ( p->packet[9] == 0x00 ) {//first frame
return pyld[startOff+1]; //FLD_FW_VERSION
for (uint8_t i = 0; i < 5; i++) {
iv->setValue(i, rec, (float) ((p->packet[(12+2*i)] << 8) + p->packet[(13+2*i)])/1);
}
iv->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]));
}
record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
rec->ts = mPayload[iv->id].ts;
iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])/1);
mPayload[iv->id].multi_parts +=4;
} 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)"));
/* according to xlsx (different start byte -1!)
byte[11] to byte[14] HW_PN
byte[15] byte[16] HW_FB_TLmValue
byte[17] byte[18] HW_FB_ReSPRT
byte[19] byte[20] HW_GridSamp_ResValule
byte[21] byte[22] HW_ECapValue
byte[23] to byte[26] Matching_APPFW_PN*/
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]));
record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure
rec->ts = mPayload[iv->id].ts;
iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1);
if(mSerialDebug) {
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]));
DPRINT(DBG_INFO,F("HW_ECapValue "));
DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21]));
DPRINT(DBG_INFO,F("Matching_APPFW_PN "));
DBGPRINTLN(String((uint32_t) (((p->packet[22] << 8) | p->packet[23]) << 8 | p->packet[24]) << 8 | p->packet[25]));
}
//notify(InverterDevInform_Simple, iv);
mPayload[iv->id].multi_parts +=2;
notify(InverterDevInform_All, iv);
} else {
DBGPRINTLN(F("3rd gen. inverter!"));
}
} else if ( p->packet[9] == 0x12 ) {//3rd frame
DPRINT_IVID(DBG_INFO, iv->id);
DBGPRINTLN(F("got 3rd frame (hw info)"));
/* according to xlsx (different start byte -1!)
byte[11] byte[12] APPFW_MINVER
byte[13] byte[14] HWInfoAddr
byte[15] byte[16] PNInfoCRC_gusv
byte[15] byte[16] PNInfoCRC_gusv (this really is double mentionned in xlsx...)
*/
if(mSerialDebug) {
DPRINT(DBG_INFO,F("APPFW_MINVER "));
DBGPRINTLN(String((p->packet[10] << 8) + p->packet[11]));
DPRINT(DBG_INFO,F("HWInfoAddr "));
DBGPRINTLN(String((p->packet[12] << 8) + p->packet[13]));
DPRINT(DBG_INFO,F("PNInfoCRC_gusv "));
DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15]));
}
mPayload[iv->id].multi_parts++;
}
if (mPayload[iv->id].multi_parts > 5) {
iv->setQueuedCmdFinished();
mPayload[iv->id].complete = true;
mPayload[iv->id].requested= false;
mStat->rxSuccess++;
}
} }
*/
void reset(uint8_t id, bool clrSts = false) { void reset(uint8_t id, bool clrSts = false) {
//DPRINT_IVID(DBG_INFO, id);
//DBGPRINTLN(F("resetPayload"));
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].rtrRes = 0;
mPayload[id].lastFound = false;*/ mPayload[id].multi_parts = 0;
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[CH0] = true; //required for 1CH and 2CH devices
@ -796,8 +756,6 @@ const byteAssign_t InfoAssignment[] = {
} }
} }
IApp *mApp; IApp *mApp;
HMSYSTEM *mSys; HMSYSTEM *mSys;
HMRADIO *mRadio; HMRADIO *mRadio;

Loading…
Cancel
Save